昵称:<._python 同时建立多个websocket">
当前位置:   article > 正文

python3 实现多人websocket聊天室_python 同时建立多个websocket

python 同时建立多个websocket

python 版本:python3.7.4

前端网页

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <div>
  9. <h3>昵称:<input type="text" id="user"/></h3>
  10. <input type="text" value="说:" id="say" hidden/>
  11. <h3>发送消息:</h3><input type="text" id="txt" style="height: 100px;width: 200px"/><br>
  12. <input type="button" id="btn" value="提交" style="height: 30px" onclick="sendMsg();"/>
  13. <input type="reset" value="reset" onclick=location="websocket.html">
  14. <input type="button" id="close" value="关闭连接" onclick="closeConn();"/>
  15. </div>
  16. <div id="content"></div>
  17. <script type="text/javascript">
  18. var socket = new WebSocket("ws://127.0.0.1:9999/chatsocket");
  19. socket.onopen = function () {
  20. var newTag = document.createElement('div');
  21. newTag.innerHTML = "【连接成功】";
  22. document.getElementById('content').appendChild(newTag);
  23. };
  24. socket.onmessage = function (event) {
  25. var response = event.data;
  26. var newTag = document.createElement('div');
  27. newTag.innerHTML = response;
  28. document.getElementById('content').appendChild(newTag);
  29. };
  30. socket.onclose = function (event) {
  31. var newTag = document.createElement('div');
  32. newTag.innerHTML = "【连接失败】";
  33. document.getElementById('content').appendChild(newTag);
  34. };
  35. function sendMsg() {
  36. var txt = document.getElementById('txt');
  37. var user = document.getElementById('user');
  38. var say = document.getElementById('say');
  39. socket.send(user.value+say.value+txt.value);
  40. txt.value = "";
  41. }
  42. function closeConn() {
  43. socket.close();
  44. var newTag = document.createElement('div');
  45. newTag.innerHTML = "【关闭连接】";
  46. document.getElementById('content').appendChild(newTag);
  47. }
  48. </script>
  49. </body>
  50. </html>

后端python代码:

  1. from socket import *
  2. import socket
  3. import base64
  4. import hashlib
  5. import threading
  6. def get_headers(data):
  7. header_dict = {}
  8. data = str(data, encoding='utf-8')
  9. header, body = data.split('\r\n\r\n', 1)
  10. header_list = header.split('\r\n')
  11. for i in range(0, len(header_list)):
  12. if i == 0:
  13. if len(header_list[i].split(' ')) == 3:
  14. header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')
  15. else:
  16. k, v = header_list[i].split(':', 1)
  17. header_dict[k] = v.strip()
  18. return header_dict
  19. def send_msg(conn, msg_bytes):
  20. import struct
  21. token = b"\x81"
  22. length = len(msg_bytes)
  23. if length < 126:
  24. token += struct.pack("B", length)
  25. elif length <= 0xFFFF:
  26. token += struct.pack("!BH", 126, length)
  27. else:
  28. token += struct.pack("!BQ", 127, length)
  29. msg = token + msg_bytes
  30. conn.send(msg)
  31. return True
  32. class Chat:
  33. def __init__(self,ip='0.0.0.0',port=9999):
  34. self.addr=(ip,port)
  35. self.sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  36. self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  37. self.client= {}
  38. def start(self,):
  39. self.sock.bind((self.addr))
  40. self.sock.listen()
  41. threading.Thread(target=self.accept,name='accept').start()
  42. def accept(self):
  43. while True:
  44. conn, address = self.sock.accept()
  45. self.client[address] = conn
  46. data = conn.recv(1024)
  47. headers = get_headers(data)
  48. response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
  49. "Upgrade:websocket\r\n" \
  50. "Connection: Upgrade\r\n" \
  51. "Sec-WebSocket-Accept: %s\r\n" \
  52. "WebSocket-Location: ws://%s%s\r\n\r\n"
  53. magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
  54. value = headers['Sec-WebSocket-Key'] + magic_string
  55. ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
  56. response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])
  57. conn.send(bytes(response_str, encoding='utf-8'))
  58. threading.Thread(target=self.recv,name='sock',args=(conn,)).start()
  59. def recv(self,sock):
  60. while 1:
  61. try:
  62. info = sock.recv(8096)
  63. except Exception as e:
  64. info = None
  65. if not info:
  66. break
  67. payload_len = info[1] & 127
  68. if payload_len == 126:
  69. extend_payload_len = info[2:4]
  70. mask = info[4:8]
  71. decoded = info[8:]
  72. elif payload_len == 127:
  73. extend_payload_len = info[2:10]
  74. mask = info[10:14]
  75. decoded = info[14:]
  76. else:
  77. extend_payload_len = None
  78. mask = info[2:6]
  79. decoded = info[6:]
  80. bytes_list = bytearray()
  81. for i in range(len(decoded)):
  82. chunk = decoded[i] ^ mask[i % 4]
  83. bytes_list.append(chunk)
  84. body = str(bytes_list, encoding='utf-8')
  85. for s in self.client.values():
  86. send_msg(s, bytes(body, encoding='utf-8'))
  87. def stop(self):
  88. for s in self.client.values():
  89. s.close()
  90. self.sock.close()
  91. sc=Chat()
  92. sc.start()

使用9999端口,启用脚本时确保端口没有被占用

测试:

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