【问题标题】:Converting websocket code from Python to Javascript将 websocket 代码从 Python 转换为 Javascript
【发布时间】:2021-10-21 10:26:40
【问题描述】:

我在将客户端 Python 代码实现为 Javascript 时遇到问题,因为 open 侦听器似乎从未被调用过

Python 代码

HEADER_LENGTH = 10
IP = "SERVER_IP"
PORT = 8080

my_username = "user" # input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)

username = my_username.encode("utf-8")
username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(username_header + username)

服务器日志将显示

Waiting for next event
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('SERVER_INTERNAL_IP', 8080)>
is notified_socket <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('SERVER_INTERNAL_IP', 8080), raddr=('CLIENT_IP', 3237)> ('CLIENT_IP', 3237)
receive_message
Accepted new connection from CLIENT_IP:3237 username:user
 
Waiting for next event
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('SERVER_INTERNAL_IP', 8080), raddr=('CLIENT_IP', 3237)>
Closed connection from user

Javascript 代码

const HEADER_LENGTH = 10;

function addSpace(str, length) {
    var adding = length - str.length;
    var copy = str;
    if (adding > 0)
        for (var i = 0; i < adding; i++)
            copy += " ";
    return copy
}

(function(){
    ws = new WebSocket("ws://" + SERVER_IP + ":8080");
    ws.addEventListener('open', function(e){
        console.log('open', e);
        var username = encodeURI("user");
        var username_header = encodeURI(addSpace(username, HEADER_LENGTH));
        ws.send(username_header + username);
    });
    ws.addEventListener('message', function(e){console.log('msg', e)});

})();

服务器日志将显示

Waiting for next event
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('SERVER_INTERNAL_IP', 8080)>
is notified_socket <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('SERVER_INTERNAL_IP', 8080), raddr=('CLIENT_IP', 3409)> ('CLIENT_IP', 3409)
 
Waiting for next event

似乎从未调用过打开的侦听器,控制台将返回错误 WebSocket connection to 'ws://SERVER_IP:8080/' failed

关于检查 Python 代码和 Javascript 代码之间区别的任何建议

【问题讨论】:

    标签: python node.js sockets websocket


    【解决方案1】:

    我将 gevent 用于此类异步情况。我喜欢它结合了普通的 html 套接字并在看到 websocket 尝试时进行升级,使整个应用程序非常优雅和简单。

    以下是bottle.pygevent-websocket 的示例:

    import gevent
    from gevent import monkey, signal, Timeout, sleep 
    monkey.patch_all()
    import signal
    from gevent import signal_handler as sig
    from gevent.pywsgi import WSGIServer
    from geventwebsocket.handler import WebSocketHandler
    from geventwebsocket import WebSocketError
    import bottle
    from bottle import get, post, template, request, response, route, abort
    
    
    @get('/')
    def _index():
        return template('index.html')
    
    #websocket
    @route('/ws/app')
    def handle_websocket():
        ws = request.environ.get('wsgi.websocket')
        if not ws:
            abort(400, 'Expected WebSocket request.')
        ws.send('CONNECTED')
        while 1:
            message = None
            try:
                # The Timeout continues the polling after 2 seconds
                # as to not block on a recieve call. Allows for data update.  
                with Timeout(2, False) as timeout:
                    message = ws.receive()
                if message:
                    #do something with the message
                    print(message)
            except WebSocketError:
                break
            except Exception as exc:
                sleep(1)
    
    
    if __name__ == '__main__':
        botapp = bottle.app()
        server = WSGIServer(("0.0.0.0", 80), botapp, handler_class=WebSocketHandler)
        def shutdown():
            print('Shutting down ...')
            server.stop(timeout=60)
            exit(signal.SIGTERM)
        sig(signal.SIGTERM, shutdown)
        sig(signal.SIGINT, shutdown)  # CTRL C
        server.serve_forever()
    

    Javascript 看起来有点像这样:

    var ws = new ReconnectingWebSocket('ws://localhost');
    ws.reconnectInterval = 3000;
    ws.maxReconnectAttempts = 100;
    
    ws.onmessage = function (evt) {
        var wsmsg = JSON.parse(evt.data);
        // Do something with the wsmsg
        }
    

    【讨论】:

    • 嗨。你能解释一下python代码connect与Javascriptnew Websocket(...)的不同之处吗?
    • javascript 是 web 连接到 python 服务器的方式。因此,您可以使用任何 websocket javascript 库来连接和处理(或发送)消息到 websocket。
    • 您介意看一下代码,因为我认为这应该是语法问题吗?谢谢
    • 我不确定你在问什么。我的代码是正确的。
    猜你喜欢
    • 2011-01-21
    • 2021-12-24
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多