当前位置:   article > 正文

python webserver 多线程_Python上的多线程websocket服务器

websocket python 多线程

请帮助我改进此代码:import base64

import hashlib

import threading

import socket

class WebSocketServer:

def __init__(self, host, port, limit, **kwargs):

"""

Initialize websocket server.

:param host: Host name as IP address or text definition.

:param port: Port number, which server will listen.

:param limit: Limit of connections in queue.

:param kwargs: A dict of key/value pairs. It MAY contains:

onconnect - function, called after client connected.

handshake - string, containing the handshake pattern.

magic - string, containing "magic" key, required for "handshake".

:type host: str

:type port: int

:type limit: int

:type kwargs: dict

"""

self.host = host

self.port = port

self.limit = limit

self.running = False

self.clients = []

self.args = kwargs

def start(self):

"""

Start websocket server.

"""

self.root = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.root.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

self.root.bind((self.host, self.port))

self.root.listen(self.limit)

self.running = True

while self.running:

client, address = self.root.accept()

if not self.running: break

self.handshake(client)

self.clients.append((client, address))

onconnect = self.args.get("onconnect")

if callable(onconnect): onconnect(self, client, address)

threading.Thread(target=self.loop, args=(client, address)).start()

self.root.close()

def stop(self):

"""

Stop websocket server.

"""

self.running = False

def handshake(self, client):

handshake = 'HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Accept: %s\r\n\r\n'

handshake = self.args.get('handshake', handshake)

magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

magic = self.args.get('magic', magic)

header = str(client.recv(1000))

try:

res = header.index("Sec-WebSocket-Key")

except ValueError:

return False

key = header[res + 19: res + 19 + 24]

key += magic

key = hashlib.sha1(key.encode())

key = base64.b64encode(key.digest())

client.send(bytes((handshake % str(key,'utf-8')), 'utf-8'))

return True

def loop(self, client, address):

"""

:type client: socket

"""

while True:

message = ''

m = client.recv(1)

while m != '':

message += m

m = client.recv(1)

fin, text = self.decodeFrame(message)

if not fin:

onmessage = self.args.get('onmessage')

if callable(onmessage): onmessage(self, client, text)

else:

self.clients.remove((client, address))

ondisconnect = self.args.get('ondisconnect')

if callable(ondisconnect): ondisconnect(self, client, address)

client.close()

break

def decodeFrame(self, data):

if (len(data) == 0) or (data is None):

return True, None

fin = not(data[0] & 1)

if fin:

return fin, None

masked = not(data[1] & 1)

plen = data[1] - (128 if masked else 0)

mask_start = 2

if plen == 126:

mask_start = 4

plen = int.from_bytes(data[2:4], byteorder='sys.byteorder')

elif plen == 127:

mask_start = 10

plen = int.from_bytes(data[2:10], byteorder='sys.byteorder')

mask = data[mask_start:mask_start+4]

data = data[mask_start+4:mask_start+4+plen]

decoded = []

i = 0

while i < len(data):

decoded.append(data[i] ^ mask[i%4])

i+=1

text = str(bytearray(decoded), "utf-8")

return fin, text

def sendto(self, client, data, **kwargs):

"""

Send data to client. data can be of type str, bytes, bytearray, int.

:param client: Client socket for data exchange.

:param data: Data, which will be sent to the client via socket.

:type client: socket

:type data: str|bytes|bytearray|int|float

"""

if type(data) == bytes or type(data) == bytearray:

frame = data

elif type(data) == str:

frame = bytes(data, kwargs.get('encoding', 'utf-8'))

elif type(data) == int or type(data) == float:

frame = bytes(str(data), kwargs.get('encoding', 'utf-8'))

else:

return None

framelen = len(frame)

head = bytes([0x81])

if framelen < 126:

head += bytes(int.to_bytes(framelen, 1, 'big'))

elif 126 <= framelen < 0x10000:

head += bytes(126)

head += bytes(int.to_bytes(framelen, 2, 'big'))

else:

head += bytes(127)

head += bytes(int.to_bytes(framelen, 8, 'big'))

client.send(head + frame)

它工作得很好。

我希望服务器使用所有处理器核心来提高性能。本规范中的连接数量不高且不有效。如何为这种情况实现多线程解决方案?在

对不起,我的英语不好。在

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/280168
推荐阅读
相关标签
  

闽ICP备14008679号