婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Django3基于WebSocket實現WebShell的詳細過程

Django3基于WebSocket實現WebShell的詳細過程

熱門標簽:地圖標注審核表 宿遷星美防封電銷卡 ai電銷機器人源碼 西藏房產智能外呼系統要多少錢 百度地圖標注沒有了 湛江智能外呼系統廠家 外呼并發線路 長沙高頻外呼系統原理是什么 ai電話機器人哪里好

前言

最近工作中需要開發前端操作遠程虛擬機的功能,簡稱WebShell. 基于當前的技術棧為react+django,調研了一會發現大部分的后端實現都是django+channels來實現websocket服務.
大致看了下覺得這不夠有趣,翻了翻django的官方文檔發現django原生是不支持websocket的,但django3之后支持了asgi協議可以自己實現websocket服務. 于是選定
gunicorn+uvicorn+asgi+websocket+django3.2+paramiko來實現WebShell.

實現websocket服務

使用django自帶的腳手架生成的項目會自動生成asgi.py和wsgi.py兩個文件,普通應用大部分用的都是wsgi.py配合nginx部署線上服務. 這次主要使用asgi.py
實現websocket服務的思路大致網上搜一下就能找到,主要就是實現 connect/send/receive/disconnect這個幾個動作的處理方法.
這里 How to Add Websockets to a Django App without Extra Dependencies 就是一個很好的實例
, 但過于簡單........:

思路

# asgi.py 
import os

from django.core.asgi import get_asgi_application
from websocket_app.websocket import websocket_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')

django_application = get_asgi_application()


async def application(scope, receive, send):
    if scope['type'] == 'http':
        await django_application(scope, receive, send)
    elif scope['type'] == 'websocket':
        await websocket_application(scope, receive, send)
    else:
        raise NotImplementedError(f"Unknown scope type {scope['type']}")


# websocket.py
async def websocket_application(scope, receive, send):
    pass
# websocket.py
async def websocket_application(scope, receive, send):
    while True:
        event = await receive()

        if event['type'] == 'websocket.connect':
            await send({
                'type': 'websocket.accept'
            })

        if event['type'] == 'websocket.disconnect':
            break

        if event['type'] == 'websocket.receive':
            if event['text'] == 'ping':
                await send({
                    'type': 'websocket.send',
                    'text': 'pong!'
                })

實現

上面的代碼提供了思路,比較完整的可以參考這里 websockets-in-django-3-1 基本可以復用了
其中最核心的實現部分我放下面:

class WebSocket:
    def __init__(self, scope, receive, send):
        self._scope = scope
        self._receive = receive
        self._send = send
        self._client_state = State.CONNECTING
        self._app_state = State.CONNECTING

    @property
    def headers(self):
        return Headers(self._scope)

    @property
    def scheme(self):
        return self._scope["scheme"]

    @property
    def path(self):
        return self._scope["path"]

    @property
    def query_params(self):
        return QueryParams(self._scope["query_string"].decode())

    @property
    def query_string(self) -> str:
        return self._scope["query_string"]

    @property
    def scope(self):
        return self._scope

    async def accept(self, subprotocol: str = None):
        """Accept connection.
        :param subprotocol: The subprotocol the server wishes to accept.
        :type subprotocol: str, optional
        """
        if self._client_state == State.CONNECTING:
            await self.receive()
        await self.send({"type": SendEvent.ACCEPT, "subprotocol": subprotocol})

    async def close(self, code: int = 1000):
        await self.send({"type": SendEvent.CLOSE, "code": code})

    async def send(self, message: t.Mapping):
        if self._app_state == State.DISCONNECTED:
            raise RuntimeError("WebSocket is disconnected.")

        if self._app_state == State.CONNECTING:
            assert message["type"] in {SendEvent.ACCEPT, SendEvent.CLOSE}, (
                    'Could not write event "%s" into socket in connecting state.'
                    % message["type"]
            )
            if message["type"] == SendEvent.CLOSE:
                self._app_state = State.DISCONNECTED
            else:
                self._app_state = State.CONNECTED

        elif self._app_state == State.CONNECTED:
            assert message["type"] in {SendEvent.SEND, SendEvent.CLOSE}, (
                    'Connected socket can send "%s" and "%s" events, not "%s"'
                    % (SendEvent.SEND, SendEvent.CLOSE, message["type"])
            )
            if message["type"] == SendEvent.CLOSE:
                self._app_state = State.DISCONNECTED

        await self._send(message)

    async def receive(self):
        if self._client_state == State.DISCONNECTED:
            raise RuntimeError("WebSocket is disconnected.")

        message = await self._receive()

        if self._client_state == State.CONNECTING:
            assert message["type"] == ReceiveEvent.CONNECT, (
                    'WebSocket is in connecting state but received "%s" event'
                    % message["type"]
            )
            self._client_state = State.CONNECTED

        elif self._client_state == State.CONNECTED:
            assert message["type"] in {ReceiveEvent.RECEIVE, ReceiveEvent.DISCONNECT}, (
                    'WebSocket is connected but received invalid event "%s".'
                    % message["type"]
            )
            if message["type"] == ReceiveEvent.DISCONNECT:
                self._client_state = State.DISCONNECTED

        return message

縫合怪

做為合格的代碼搬運工,為了提高搬運效率還是要造點輪子填點坑的,如何將上面的WebSocket類與paramiko結合起來實現從前端接受字符傳遞給遠程主機并同時接受返回呢?

import asyncio
import traceback
import paramiko
from webshell.ssh import Base, RemoteSSH
from webshell.connection import WebSocket


class WebShell:
    """整理 WebSocket 和 paramiko.Channel,實現兩者的數據互通"""

    def __init__(self, ws_session: WebSocket,
                 ssh_session: paramiko.SSHClient = None,
                 chanel_session: paramiko.Channel = None
                 ):
        self.ws_session = ws_session
        self.ssh_session = ssh_session
        self.chanel_session = chanel_session

    def init_ssh(self, host=None, port=22, user="admin", passwd="admin@123"):
        self.ssh_session, self.chanel_session = RemoteSSH(host, port, user, passwd).session()

    def set_ssh(self, ssh_session, chanel_session):
        self.ssh_session = ssh_session
        self.chanel_session = chanel_session

    async def ready(self):
        await self.ws_session.accept()

    async def welcome(self):
        # 展示Linux歡迎相關內容
        for i in range(2):
            if self.chanel_session.send_ready():
                message = self.chanel_session.recv(2048).decode('utf-8')
                if not message:
                    return
                await self.ws_session.send_text(message)

    async def web_to_ssh(self):
        # print('--------web_to_ssh------->')
        while True:
            # print('--------------->')
            if not self.chanel_session.active or not self.ws_session.status:
                return
            await asyncio.sleep(0.01)
            shell = await self.ws_session.receive_text()
            # print('-------shell-------->', shell)
            if self.chanel_session.active and self.chanel_session.send_ready():
                self.chanel_session.send(bytes(shell, 'utf-8'))
            # print('--------------->', "end")

    async def ssh_to_web(self):
        # print('--------ssh_to_web-----------')
        while True:
            # print('-------------------')
            if not self.chanel_session.active:
                await self.ws_session.send_text('ssh closed')
                return
            if not self.ws_session.status:
                return
            await asyncio.sleep(0.01)
            if self.chanel_session.recv_ready():
                message = self.chanel_session.recv(2048).decode('utf-8')
                # print('---------message----------', message)
                if not len(message):
                    continue
                await self.ws_session.send_text(message)
            # print('-------------------', "end")

    async def run(self):
        if not self.ssh_session:
            raise Exception("ssh not init!")
        await self.ready()
        await asyncio.gather(
            self.web_to_ssh(),
            self.ssh_to_web()
        )

    def clear(self):
        try:
            self.ws_session.close()
        except Exception:
            traceback.print_stack()
        try:
            self.ssh_session.close()
        except Exception:
            traceback.print_stack()

前端

xterm.js 完全滿足,搜索下找個看著簡單的就行.

export class Term extends React.Component {
    private terminal!: HTMLDivElement;
    private fitAddon = new FitAddon();

    componentDidMount() {
        const xterm = new Terminal();
        xterm.loadAddon(this.fitAddon);
        xterm.loadAddon(new WebLinksAddon());

        // using wss for https
        //         const socket = new WebSocket("ws://" + window.location.host + "/api/v1/ws");
        const socket = new WebSocket("ws://localhost:8000/webshell/");
        // socket.onclose = (event) => {
        //     this.props.onClose();
        // }
        socket.onopen = (event) => {
            xterm.loadAddon(new AttachAddon(socket));
            this.fitAddon.fit();
            xterm.focus();
        }

        xterm.open(this.terminal);
        xterm.onResize(({ cols, rows }) => {
            socket.send("RESIZE>" + cols + "," + rows)
        });

        window.addEventListener('resize', this.onResize);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.onResize);
    }

    onResize = () => {
        this.fitAddon.fit();
    }

    render() {
        return div className="Terminal" ref={(ref) => this.terminal = ref as HTMLDivElement}>/div>;
    }
}

好了,廢話不多少了,代碼我放這里了webshell 歡迎star/fork!

參考資料

webshell

django文檔

graphene-django文檔

django 異步視圖

websockets-in-django-3-1

How to Add Websockets to a Django App without Extra Dependencies

到此這篇關于Django3使用WebSocket實現WebShell的文章就介紹到這了,更多相關Django3實現WebShell內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Django websocket原理及功能實現代碼
  • 詳解Django3中直接添加Websockets方式
  • Django通過dwebsocket實現websocket的例子
  • 詳解Django-channels 實現WebSocket實例
  • Django使用Channels實現WebSocket的方法

標簽:寧夏 大同 林芝 南平 海南 漯河 普洱 盤錦

巨人網絡通訊聲明:本文標題《Django3基于WebSocket實現WebShell的詳細過程》,本文關鍵詞  Django3,基于,WebSocket,實現,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Django3基于WebSocket實現WebShell的詳細過程》相關的同類信息!
  • 本頁收集關于Django3基于WebSocket實現WebShell的詳細過程的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日韩欧美国产小视频| 国产精品资源在线看| 国产精品欧美一区喷水| 成人涩涩免费视频| 国产亚洲欧美激情| 丁香激情综合国产| 不卡的av网站| 久久综合av免费| 色国产精品一区在线观看| 在线欧美一区二区| 亚洲色图制服诱惑| 成人免费看黄yyy456| 91天堂素人约啪| 亚洲同性gay激情无套| 成人免费看的视频| 国产精品网站一区| 三级在线观看一区二区| 国产乱理伦片在线观看夜一区| 欧美大片一区二区三区| 久久色成人在线| 日本一不卡视频| 欧美xxxxx牲另类人与| 欧美高清视频不卡网| 成人性视频网站| 一区二区不卡在线播放| 免费看黄色91| 日韩视频免费观看高清完整版| 在线一区二区观看| 亚洲精品欧美激情| 国产乱子伦一区二区三区国色天香| 一区二区三区中文在线观看| 欧美日韩国产精品成人| 日韩一区二区三区高清免费看看| 久久欧美中文字幕| 成人中文字幕在线| 亚洲日本电影在线| 色屁屁一区二区| 秋霞影院一区二区| 亚洲成人综合视频| 亚洲色图在线看| 亚洲小少妇裸体bbw| 欧美激情一区三区| 欧美另类videos死尸| 久久国产精品99久久久久久老狼 | 美女精品一区二区| 日韩av电影天堂| gogo大胆日本视频一区| 亚洲第一会所有码转帖| 欧美无砖专区一中文字| 国产精品人成在线观看免费 | www.日韩大片| 中文av字幕一区| 欧美狂野另类xxxxoooo| 中文字幕永久在线不卡| 成人国产电影网| 最新中文字幕一区二区三区| 亚洲高清视频的网址| 精品国精品国产尤物美女| 26uuu久久综合| 成人性色生活片免费看爆迷你毛片| 亚洲成人一区在线| 国产欧美一区二区三区在线老狼| 久久久久久久久一| 91精品办公室少妇高潮对白| 蜜臀99久久精品久久久久久软件| 欧美最猛性xxxxx直播| 日本欧美加勒比视频| 一区二区三区精品在线观看| 精品99久久久久久| 精品女同一区二区| 日本乱人伦一区| 一区二区久久久久| 欧美性淫爽ww久久久久无| 亚洲成人久久影院| 精品捆绑美女sm三区| 成人中文字幕在线| 欧美亚洲国产一区二区三区va | 国产成人亚洲综合色影视| 一区二区三区精品在线| 午夜电影久久久| 亚洲欧美视频在线观看视频| 国产亚洲欧美激情| 亚洲理论在线观看| 一区二区三区在线观看视频| 亚洲欧美在线观看| 6080午夜不卡| 欧美日韩一区二区在线观看| 国产成人综合自拍| 激情图片小说一区| 成人涩涩免费视频| 午夜一区二区三区在线观看| 精品毛片乱码1区2区3区| 亚洲第一成年网| 亚洲免费观看高清完整版在线观看熊 | 欧美一区二区三级| 不卡在线观看av| 7777精品伊人久久久大香线蕉的| 欧美女孩性生活视频| 亚洲天堂成人网| 亚洲已满18点击进入久久| 91污在线观看| 久久网站最新地址| 色综合色综合色综合| 1区2区3区欧美| 欧美日韩久久一区| 91精品国产综合久久精品性色| 国产精品久久综合| 久久久99免费| 国产91精品免费| 午夜欧美在线一二页| 制服丝袜av成人在线看| av中文字幕在线不卡| 欧美日韩综合色| 久久国产免费看| 成人av电影观看| 精品久久久三级丝袜| 亚洲精品久久嫩草网站秘色| 欧美性猛片aaaaaaa做受| 国产精品一二三区在线| 国产aⅴ精品一区二区三区色成熟| 国产精品久久久久婷婷二区次| 91视频一区二区| 中文字幕高清一区| 在线看不卡av| 蜜臀av一区二区在线观看| 欧美日韩电影一区| 99视频一区二区| 丝袜诱惑亚洲看片| 久久久99精品久久| 成人av午夜影院| 中文一区二区完整视频在线观看| 日韩一级片在线播放| 97se亚洲国产综合自在线不卡 | 日韩在线播放一区二区| 日韩午夜电影在线观看| 国内精品嫩模私拍在线| 视频一区二区国产| 亚洲日本成人在线观看| 夜夜嗨av一区二区三区四季av| 国产日韩高清在线| 亚洲欧洲另类国产综合| 中文字幕一区二区三区av| 尤物av一区二区| 久久国产三级精品| 亚洲美女屁股眼交3| 日韩限制级电影在线观看| 国产v综合v亚洲欧| 欧美bbbbb| 天堂av在线一区| 偷拍自拍另类欧美| 91在线你懂得| 成人黄页在线观看| 色综合久久久网| 国产成人自拍网| 色婷婷国产精品综合在线观看| 成人av在线播放网址| 国产亚洲精品bt天堂精选| 国产成人免费视频精品含羞草妖精 | 国产成人午夜电影网| 亚洲电影一级黄| 精品少妇一区二区三区在线视频| 日韩天堂在线观看| 99re热这里只有精品免费视频 | 亚洲国产精品一区二区尤物区| 国产偷国产偷亚洲高清人白洁| 1024成人网| 国产精品麻豆视频| 一区二区久久久| 国产精品欧美综合在线| 亚洲香蕉伊在人在线观| 性做久久久久久免费观看欧美| 亚洲欧美日本在线| 性做久久久久久| 综合自拍亚洲综合图不卡区| 日韩影院免费视频| 丰满放荡岳乱妇91ww| 成人黄色一级视频| 高清成人在线观看| 欧美高清视频不卡网| 欧美日韩日日骚| 国产 日韩 欧美大片| 色猫猫国产区一区二在线视频| 国产色婷婷亚洲99精品小说| 精品国产欧美一区二区| 国产精品看片你懂得| 欧美精品vⅰdeose4hd| 欧美成人video| 久久众筹精品私拍模特| 中文字幕在线不卡一区| 日本韩国欧美国产| 91美女片黄在线观看| 成人一区在线看| 97精品久久久午夜一区二区三区| 97久久久精品综合88久久| 国产女主播在线一区二区| 国产精品久久毛片a| 日本 国产 欧美色综合| 精品国精品自拍自在线| 免费观看一级特黄欧美大片| 国产精品资源网|