Python手册(11) WebSocket

0. 前言

  • 目标:建立长连接,异步发送/接收信息。
    • 注意,只关注长连接

1. Server

Method Description Takes Gives
set_fn_new_client() Sets a callback function that will be called for every new client connecting to us function None
set_fn_client_left() Sets a callback function that will be called for every client disconnecting from us function None
set_fn_message_received() Sets a callback function that will be called when a client sends a message function None
send_message() Sends a message to a specific client. The message is a simple string. client, message None
send_message_to_all() Sends a message to all connected clients. The message is a simple string. message None
  • 注意事项:

    • 当运行了 run_forever 方法后,当前线程就阻塞了。
    • 如果在之后要调用 send_message_to_all 方法,利用多线程。
  • 基本使用示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    from websocket_server import WebsocketServer

    # Called for every client connecting (after handshake)
    def new_client(client, server):
    print("New client connected and was given id %d" % client['id'])
    server.send_message_to_all("Hey all, a new client has joined us")


    # Called for every client disconnecting
    def client_left(client, server):
    print("Client(%d) disconnected" % client['id'])


    # Called when a client sends a message
    def message_received(client, server, message):
    if len(message) > 200:
    message = message[:200]+'..'
    print("Client(%d) said: %s" % (client['id'], message))


    PORT=9001
    server = WebsocketServer(PORT)
    server.set_fn_new_client(new_client)
    server.set_fn_client_left(client_left)
    server.set_fn_message_received(message_received)
    server.run_forever()
  • 多线程示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import time
import logging
import threading
from websocket_server import WebsocketServer


def new_client(client, server):
server.send_message_to_all("Hey all, a new client has joined us")


def message_received(client, server, message):
if len(message) > 200:
message = message[:200]+'..'
print("Client(%d) said: %s" % (client['id'], message))


class ServerThread(threading.Thread):
def __init__(self, port=13254, host='10.1.187.36', loglevel=logging.INFO):
threading.Thread.__init__(self)
self.server = WebsocketServer(port, host=host, loglevel=loglevel)
self.server.set_fn_new_client(new_client)
self.server.set_fn_message_received(message_received)
print('init server thread successfully')

def run(self):
print("start running server thread")
self.server.run_forever()


if __name__ == '__main__':
server_thread = ServerThread()
server_thread.start()
while True:
time.sleep(5)
server_thread.server.send_message_to_all('server test msg')

2. Cleint

  • 参考:Github: websocket-client/websocket-client

  • 安装:pip install websocket-clien

  • 注意事项:

    • url的结构形如 ws://host:ip,可能还要设置。
    • run_forever 运行后会阻塞当前线程,如果想要执行其他功能,需要设置多线程。
  • 简单示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import websocket
    try:
    import thread
    except ImportError:
    import _thread as thread
    import time

    def on_message(ws, message):
    print(message)

    def on_error(ws, error):
    print(error)

    def on_close(ws):
    print("### closed ###")

    def on_open(ws):
    def run(*args):
    for i in range(3):
    time.sleep(1)
    ws.send("Hello %d" % i)
    time.sleep(1)
    ws.close()
    print("thread terminating...")
    thread.start_new_thread(run, ())


    if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://echo.websocket.org/",
    on_message = on_message,
    on_error = on_error,
    on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()
  • 多线程示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    import websocket
    import threading
    websocket.enableTrace(True)


    def on_message(ws, message):
    print('on message')
    print(ws)
    print(message)


    def on_error(ws, error):
    print('on error')
    print(ws)
    print(error)


    def on_close(ws):
    print('on close')
    print(ws)
    print("### closed ###")


    class ClientThread(threading.Thread):
    def __init__(self, port=13254, host="10.1.187.36"):
    threading.Thread.__init__(self)
    url = "ws://{}:{}".format(host, port)
    self.ws = websocket.WebSocketApp(url,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close)
    print('successfully creating client thread')

    def run(self):
    self.ws.run_forever()


    if __name__ == '__main__':
    client_thread = ClientThread()
    client_thread.start()

    import time
    while True:
    time.sleep(5)
    client_thread.ws.send('client test msg')