日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

python---websocket的使用

發(fā)布時間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python---websocket的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一:簡介

推文:WebSocket 是什么原理?為什么可以實現(xiàn)持久連接?

推文:WebSocket:5分鐘從入門到精通(很好)

WebSocket協(xié)議是基于TCP的一種新的協(xié)議。WebSocket最初在HTML5規(guī)范中被引用為TCP連接,作為基于TCP的套接字API的占位符。它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信。其本質(zhì)是保持TCP連接,在瀏覽器和服務(wù)端通過Socket進行通信。

二:對比:

Http:

  socket實現(xiàn),單工通道(瀏覽器只發(fā)起,服務(wù)端只做響應(yīng)),短連接,請求響應(yīng)

WebSocket:

  socket實現(xiàn),雙工通道,請求響應(yīng),推送。socket創(chuàng)建連接,不斷開

三:socket實現(xiàn)步驟

服務(wù)端:

1. 服務(wù)端開啟socket,監(jiān)聽IP和端口
3. 允許連接
* 5. 服務(wù)端接收到特殊值【加密sha1,特殊值,migic string="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"* 6. 加密后的值發(fā)送給客戶端

客戶端:

2. 客戶端發(fā)起連接請求(IP和端口)
* 4. 客戶端生成一個xxx,【加密sha1,特殊值,migic string="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"】,向服務(wù)端發(fā)送一段特殊值
* 7. 客戶端接收到加密的值

注意:這個魔數(shù)是固定的 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

四:簡單實現(xiàn),實現(xiàn)連接

服務(wù)端:

# coding:utf8
# __author:  Administrator
# date:      2018/6/29 0029
# /usr/bin/env python
import socket,base64,hashlibdef get_headers(data):'''將請求頭轉(zhuǎn)換為字典'''header_dict = {}data = str(data,encoding="utf-8")header,body = data.split("\r\n\r\n",1)header_list = header.split("\r\n")for i in range(0,len(header_list)):if i == 0:if len(header_list[0].split(" ")) == 3:header_dict['method'],header_dict['url'],header_dict['protocol'] = header_list[0].split(" ")else:k,v=header_list[i].split(":",1)header_dict[k]=v.strip()return header_dictsock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(("127.0.0.1",8080))
sock.listen(5)#等待用戶連接
conn,addr = sock.accept()
print("conn from ",conn,addr)
#獲取握手消息,magic string ,sha1加密
#發(fā)送給客戶端
#握手消息
data = conn.recv(8096)
headers = get_headers(data)# 對請求頭中的sec-websocket-key進行加密
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \"Upgrade:websocket\r\n" \"Connection: Upgrade\r\n" \"Sec-WebSocket-Accept: %s\r\n" \"WebSocket-Location: ws://%s%s\r\n\r\n"magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])# 響應(yīng)【握手】信息
conn.send(bytes(response_str, encoding='utf-8'))
'''
b'
GET / HTTP/1.1\r\n
Host: 127.0.0.1:8080\r\n
Connection: Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade: websocket\r\n
Origin: http://localhost:63342\r\n
Sec-WebSocket-Version: 13\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.8\r\n
Sec-WebSocket-Key: +uL/aiakjNABjEoMzAqm6Q==\r\n
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n'
'''
請求頭

瀏覽器:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body></body>
</html>
<script>ws =new WebSocket("ws://127.0.0.1:8080");ws.onopen = function (ev) { //若是連接成功,onopen函數(shù)會執(zhí)行console.log(22222)}
</script>

五:數(shù)據(jù)接收規(guī)則

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |  #Payload len(第二個字節(jié)的前七位,最大127)決定頭部的長度
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |  #若是小于126:Extended payload length擴展頭部長度為0字節(jié),后面全部為主體數(shù)據(jù)
|N|V|V|V|       |S|             |   (if payload len==126/127)   |  #若是等于126:Extended payload length擴展頭部長度為2字節(jié),后面全部為主體數(shù)據(jù)
| |1|2|3|       |K|             |                               |  #若是等于127:Extended payload length擴展頭部長度為8字節(jié),后面全部為主體數(shù)據(jù)
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |  #注意:主體數(shù)據(jù)中的前四位為mask掩碼,用于后面的消息的解碼,解碼方式為循環(huán)異或操作
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |  #數(shù)據(jù)過長,需要分部發(fā)送,這時需要FIN和opcode
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
The MASK bit simply tells whether the message is encoded. Messages from the client must be masked, so your server should expect this to be 1. (In fact, section 5.1 of the spec says that your server must disconnect from a client if that client sends an unmasked message.) When sending a frame back to the client, do not mask it and do not set the mask bit. We'll explain masking later. Note: You have to mask messages even when using a secure socket.RSV1-3 can be ignored, they are for extensions.

The opcode field defines how to interpret the payload data: 0x0 for continuation, 0x1 for text (which is always encoded in UTF-8), 0x2 for binary, and other so-called "control codes" that will be discussed later. In this version of WebSockets, 0x3 to 0x7 and 0xB to 0xF have no meaning.The FIN bit tells whether this is the last message in a series. If it's 0, then the server will keep listening for more parts of the message; otherwise, the server should consider the message delivered. More on this later.

Decoding Payload LengthTo read the payload data, you must know when to stop reading. That's why the payload length is important to know. Unfortunately, this is somewhat complicated. To read it, follow these steps:

Read bits 9-15 (inclusive) and interpret that as an unsigned integer. If it's 125 or less, then that's the length; you're done. If it's 126, go to step 2. If it's 127, go to step 3.
Read the next 16 bits and interpret those as an unsigned integer. You're done.
Read the next 64 bits and interpret those as an unsigned integer (The most significant bit MUST be 0). You're done.
Reading and Unmasking the DataIf the MASK bit was set (and it should be, for client-to-server messages), read the next 4 octets (32 bits); this is the masking key. Once the payload length and masking key is decoded, you can go ahead and read that number of bytes from the socket. Let's call the data ENCODED, and the key MASK. To get DECODED, loop through the octets (bytes a.k.a. characters for text data) of ENCODED and XOR the octet with the (i modulo 4)th octet of MASK. In pseudo-code (that happens to be valid JavaScript):var DECODED = "";
for (var i = 0; i < ENCODED.length; i++) {DECODED[i] = ENCODED[i] ^ MASK[i % 4];
}Now you can figure out what DECODED means depending on your application.
View Code

數(shù)據(jù)幀格式:

FIN:1個比特。

如果是1,表示這是消息(message)的最后一個分片(fragment),如果是0,表示不是是消息(message)的最后一個分片(fragment)。

RSV1, RSV2, RSV3:各占1個比特。

一般情況下全為0。當客戶端、服務(wù)端協(xié)商采用WebSocket擴展時,這三個標志位可以非0,且值的含義由擴展進行定義。如果出現(xiàn)非零的值,且并沒有采用WebSocket擴展,連接出錯。

Opcode: 4個比特。

操作代碼,Opcode的值決定了應(yīng)該如何解析后續(xù)的數(shù)據(jù)載荷(data payload)。如果操作代碼是不認識的,那么接收端應(yīng)該斷開連接(fail the connection)。可選的操作代碼如下:%x0:表示一個延續(xù)幀。當Opcode為0時,表示本次數(shù)據(jù)傳輸采用了數(shù)據(jù)分片,當前收到的數(shù)據(jù)幀為其中一個數(shù)據(jù)分片。
%x1:表示這是一個文本幀(frame)
%x2:表示這是一個二進制幀(frame)
%x3-7:保留的操作代碼,用于后續(xù)定義的非控制幀。
%x8:表示連接斷開。
%x9:表示這是一個ping操作。
%xA:表示這是一個pong操作。
%xB-F:保留的操作代碼,用于后續(xù)定義的控制幀。

Mask: 1個比特。

表示是否要對數(shù)據(jù)載荷進行掩碼操作。從客戶端向服務(wù)端發(fā)送數(shù)據(jù)時,需要對數(shù)據(jù)進行掩碼操作;從服務(wù)端向客戶端發(fā)送數(shù)據(jù)時,不需要對數(shù)據(jù)進行掩碼操作。如果服務(wù)端接收到的數(shù)據(jù)沒有進行過掩碼操作,服務(wù)端需要斷開連接。如果Mask是1,那么在Masking-key中會定義一個掩碼鍵(masking key),并用這個掩碼鍵來對數(shù)據(jù)載荷進行反掩碼。所有客戶端發(fā)送到服務(wù)端的數(shù)據(jù)幀,Mask都是1。掩碼的算法、用途在下一小節(jié)講解。

Payload length:數(shù)據(jù)載荷的長度,單位是字節(jié)。為7位,或7+16位,或1+64位。

假設(shè)數(shù)Payload length === x,如果x為0~126:數(shù)據(jù)的長度為x字節(jié)。
x為126:后續(xù)2個字節(jié)代表一個16位的無符號整數(shù),該無符號整數(shù)的值為數(shù)據(jù)的長度。
x為127:后續(xù)8個字節(jié)代表一個64位的無符號整數(shù)(最高位為0),該無符號整數(shù)的值為數(shù)據(jù)的長度。
此外,如果payload length占用了多個字節(jié)的話,payload length的二進制表達采用網(wǎng)絡(luò)序(big endian,重要的位在前)。

Masking-key:0或4字節(jié)(32位)

所有從客戶端傳送到服務(wù)端的數(shù)據(jù)幀,數(shù)據(jù)載荷都進行了掩碼操作,Mask為1,且攜帶了4字節(jié)的Masking-key。如果Mask為0,則沒有Masking-key。備注:載荷數(shù)據(jù)的長度,不包括mask key的長度。

Payload data:(x+y) 字節(jié)

載荷數(shù)據(jù):包括了擴展數(shù)據(jù)、應(yīng)用數(shù)據(jù)。其中,擴展數(shù)據(jù)x字節(jié),應(yīng)用數(shù)據(jù)y字節(jié)。擴展數(shù)據(jù):如果沒有協(xié)商使用擴展的話,擴展數(shù)據(jù)數(shù)據(jù)為0字節(jié)。所有的擴展都必須聲明擴展數(shù)據(jù)的長度,或者可以如何計算出擴展數(shù)據(jù)的長度。此外,擴展如何使用必須在握手階段就協(xié)商好。如果擴展數(shù)據(jù)存在,那么載荷數(shù)據(jù)長度必須將擴展數(shù)據(jù)的長度包含在內(nèi)。應(yīng)用數(shù)據(jù):任意的應(yīng)用數(shù)據(jù),在擴展數(shù)據(jù)之后(如果存在擴展數(shù)據(jù)),占據(jù)了數(shù)據(jù)幀剩余的位置。載荷數(shù)據(jù)長度 減去 擴展數(shù)據(jù)長度,就得到應(yīng)用數(shù)據(jù)的長度。

實現(xiàn)規(guī)則解碼:

def get_data(info):    #info是我們連接后,接受的數(shù)據(jù)payload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()    #這里我們使用字節(jié)將數(shù)據(jù)全部收集,再去字符串編碼,這樣不會導(dǎo)致中文亂碼for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]bytes_list.append(chunk)body = str(bytes_list, encoding='utf-8')return body

?實現(xiàn)循環(huán)獲取數(shù)據(jù)

import socket,base64,hashlibdef get_headers(data):'''將請求頭轉(zhuǎn)換為字典'''header_dict = {}data = str(data,encoding="utf-8")header,body = data.split("\r\n\r\n",1)header_list = header.split("\r\n")for i in range(0,len(header_list)):if i == 0:if len(header_list[0].split(" ")) == 3:header_dict['method'],header_dict['url'],header_dict['protocol'] = header_list[0].split(" ")else:k,v=header_list[i].split(":",1)header_dict[k]=v.strip()return header_dictdef get_data(info):payload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()    #這里我們使用字節(jié)將數(shù)據(jù)全部收集,再去字符串編碼,這樣不會導(dǎo)致中文亂碼for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]    #解碼方式bytes_list.append(chunk)body = str(bytes_list, encoding='utf-8')return bodysock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(("127.0.0.1",8080))
sock.listen(5)#等待用戶連接
conn,addr = sock.accept()
print("conn from ",conn,addr)
#獲取握手消息,magic string ,sha1加密
#發(fā)送給客戶端
#握手消息
data = conn.recv(8096)headers = get_headers(data)# 對請求頭中的sec-websocket-key進行加密
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \"Upgrade:websocket\r\n" \"Connection: Upgrade\r\n" \"Sec-WebSocket-Accept: %s\r\n" \"WebSocket-Location: ws://%s%s\r\n\r\n"magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])# 響應(yīng)【握手】信息
conn.send(bytes(response_str, encoding='utf-8'))#可以進行通信
while True:data = conn.recv(8096)data = get_data(data)print(data)
服務(wù)端代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body></body>
</html>
<script>ws =new WebSocket("ws://127.0.0.1:8080");ws.onopen = function (ev) { //若是連接成功,onopen函數(shù)會執(zhí)行console.log(22222);ws.send("你好");}
</script>
客戶端代碼

注意:使用控制臺完成發(fā)送,而不是刷新頁面,會報錯,因為我們關(guān)閉了連接,試圖將關(guān)閉信號字節(jié)編碼出錯。這里我們需要利用mask(第二字節(jié)中,1表示連接,0斷開)

六:數(shù)據(jù)發(fā)送規(guī)則(需要發(fā)送二進制包struct模塊)

def send_msg(conn, msg_bytes):  """
    WebSocket服務(wù)端向客戶端發(fā)送消息:param conn: 客戶端連接到服務(wù)器端的socket對象,即: conn,address = socket.accept():param msg_bytes: 向客戶端發(fā)送的字節(jié):return: """
    import structtoken = b"\x81"  #接收的第一字節(jié),一般都是x81不變length = len(msg_bytes)if length < 126:token += struct.pack("B", length)elif length <= 0xFFFF:token += struct.pack("!BH", 126, length)else:token += struct.pack("!BQ", 127, length)msg = token + msg_bytesconn.send(msg)return True

實現(xiàn)發(fā)送數(shù)據(jù)

# coding:utf8
# __author:  Administrator
# date:      2018/6/29 0029
# /usr/bin/env python
import socket,base64,hashlibdef get_headers(data):'''將請求頭轉(zhuǎn)換為字典'''header_dict = {}data = str(data,encoding="utf-8")header,body = data.split("\r\n\r\n",1)header_list = header.split("\r\n")for i in range(0,len(header_list)):if i == 0:if len(header_list[0].split(" ")) == 3:header_dict['method'],header_dict['url'],header_dict['protocol'] = header_list[0].split(" ")else:k,v=header_list[i].split(":",1)header_dict[k]=v.strip()return header_dictdef get_data(info):payload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()    #這里我們使用字節(jié)將數(shù)據(jù)全部收集,再去字符串編碼,這樣不會導(dǎo)致中文亂碼for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]    #解碼方式bytes_list.append(chunk)body = str(bytes_list, encoding='utf-8')return bodydef send_msg(conn, msg_bytes):"""
    WebSocket服務(wù)端向客戶端發(fā)送消息:param conn: 客戶端連接到服務(wù)器端的socket對象,即: conn,address = socket.accept():param msg_bytes: 向客戶端發(fā)送的字節(jié):return:"""
    import structtoken = b"\x81" #接收的第一字節(jié),一般都是x81不變length = len(msg_bytes)if length < 126:token += struct.pack("B", length)elif length <= 0xFFFF:token += struct.pack("!BH", 126, length)else:token += struct.pack("!BQ", 127, length)msg = token + msg_bytesconn.send(msg)return Truesock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(("127.0.0.1",8080))
sock.listen(5)#等待用戶連接
conn,addr = sock.accept()
#獲取握手消息,magic string ,sha1加密
#發(fā)送給客戶端
#握手消息
data = conn.recv(8096)headers = get_headers(data)# 對請求頭中的sec-websocket-key進行加密
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \"Upgrade:websocket\r\n" \"Connection: Upgrade\r\n" \"Sec-WebSocket-Accept: %s\r\n" \"WebSocket-Location: ws://%s%s\r\n\r\n"magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])# 響應(yīng)【握手】信息
conn.send(bytes(response_str, encoding='utf-8'))#可以進行通信
while True:data = conn.recv(8096)data = get_data(data)print(data)send_msg(conn,bytes(data+"geah",encoding="utf-8"))
服務(wù)端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body></body>
</html>
<script>ws =new WebSocket("ws://127.0.0.1:8080");ws.onopen = function (ev) { //若是連接成功,onopen函數(shù)會執(zhí)行console.log(22222);ws.send("你好");}ws.onmessage = function (ev) {console.log(ev);}
</script>
前端onmessage 當數(shù)據(jù)接收會觸發(fā)

七:tornado實現(xiàn)websocket聊天室

?tornado服務(wù)端

import tornado.ioloop
import tornado.web
import tornado.websocket
import datetimeclass MainHandler(tornado.web.RequestHandler):def get(self):self.render("s1.html")def post(self, *args, **kwargs):passusers = set()
class ChatHandler(tornado.websocket.WebSocketHandler):def open(self, *args, **kwargs):'''客戶端連接'''print("connect....")print(self.request)users.add(self)def on_message(self, message):'''有消息到達'''now = datetime.datetime.now()content = self.render_string("recv_msg.html",date=now.strftime("%Y-%m-%d %H:%M:%S"),msg=message)for client in users:if client == self:continueclient.write_message(content)def on_close(self):'''客戶端主動關(guān)閉連接'''users.remove(self)st ={"template_path": "template",#模板路徑配置"static_path":'static',
}#路由映射   匹配執(zhí)行,否則404
application = tornado.web.Application([("/index",MainHandler),("/wschat",ChatHandler),
],**st)if __name__=="__main__":application.listen(8080)#io多路復(fù)用tornado.ioloop.IOLoop.instance().start()

前端模板

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link href="/static/css/bootstrap.min.css" rel="stylesheet"><link href="/static/css/nifty.min.css" rel="stylesheet"><link href="/static/css/demo/nifty-demo-icons.min.css" rel="stylesheet"><link href="/static/css/demo/nifty-demo.min.css" rel="stylesheet"><link href="/static/plugins/pace/pace.min.css" rel="stylesheet"><script src="/static/js/jquery-2.2.4.min.js"></script><script src="/static/plugins/pace/pace.min.js"></script><script src="/static/js/bootstrap.min.js"></script><script src="/static/js/nifty.min.js"></script><script src="/static/js/demo/nifty-demo.min.js"></script><script src="/static/plugins/flot-charts/jquery.flot.min.js"></script><script src="/static/plugins/flot-charts/jquery.flot.resize.min.js"></script><script src="/static/plugins/gauge-js/gauge.min.js"></script><script src="/static/plugins/skycons/skycons.min.js"></script><script src="/static/plugins/easy-pie-chart/jquery.easypiechart.min.js"></script><script src="/static/js/demo/widgets.js"></script>
</head>
<body>
<div id="container" class="effect  aside-bright mainnav-sm aside-right aside-in"><div class="boxed"><div id="content-container"><div class="row"><div class="col-md-8 col-lg-8 col-sm-8"><!--Chat widget--><!--===================================================--><div class="panel" style="height: 640px"><!--Heading--><div class="panel-heading"><h3 class="panel-title">Chat</h3></div><!--Widget body--><div style="height:510px;padding-top:0px;" class="widget-body"><div class="nano"><div class="nano-content pad-all"><ul class="list-unstyled media-block"></ul></div></div><!--Widget footer--><div class="panel-footer" style="height: 90px;"><div class="row"><div class="col-xs-9"><input type="text" placeholder="Enter your text" class="form-control chat-input"></div><div class="col-xs-3"><button class="btn btn-primary btn-block" οnclick="sendMsg(this);" type="submit">Send</button></div></div></div></div></div><!--===================================================--><!--Chat widget--></div><div class="col-md-4 col-lg-4 col-sm-4"><aside id="aside-container"><div id="aside"><div class="nano has-scrollbar"><div class="nano-content" tabindex="0" style="right: -17px;"><!--Nav tabs--><!--================================--><ul class="nav nav-tabs nav-justified"><li class="active"><a href="#demo-asd-tab-1" data-toggle="tab"><i class="demo-pli-speech-bubble-7"></i></a></li></ul><!--================================--><!--End nav tabs--><!-- Tabs Content --><!--================================--><div class="tab-content"><div class="tab-pane fade in active" id="demo-asd-tab-1"><p class="pad-hor text-semibold text-main"><span class="pull-right badge badge-success">0</span> Friends</p></div></div></div><div class="nano-pane" style="display: none;"><div class="nano-slider" style="height: 4059px; transform: translate(0px, 0px);"></div></div></div></div></aside></div></div></div></div>
</div>
</body>
</html><script>ws = new WebSocket("ws://127.0.0.1:8080/wschat");function sendMsg(ths) {var dt = new Date()var now_time = dt.toLocaleString();var msg = $(ths).parents(".row").find(".chat-input").val();$(ths).parents(".row").find(".chat-input").empty();var li = '<li class="mar-btm"><div class="media-right"><img src="" class="img-circle img-sm" alt="Profile Picture"></div>';li += '<div class="media-body pad-hor speech-right"><div class="speech"><a href="#" class="media-heading">游客</a>';li += '<p>'+msg+'</p>';li += '<p class="speech-time">';li += '<i class="demo-pli-clock icon-fw"></i>'+now_time;li += '</p></div></div></li>';$(ths).parents(".widget-body").find(".list-unstyled").append(li);$(ths).parents(".panel-footer").find(".chat-input").val("");ws.send(msg);}ws.onmessage=function (ev) {$(".list-unstyled").append(ev.data);}
</script>
s1.html

消息插件

                                <li class="mar-btm"><div class="media-left"><img src="img/profile-photos/1.png" class="img-circle img-sm" alt="Profile Picture"></div><div class="media-body pad-hor"><div class="speech"><a href="#" class="media-heading">游客</a><p>{{msg}}</p><p class="speech-time"><i class="demo-pli-clock icon-fw"></i>{{date}}</p></div></div></li>
recv_msg.html

實現(xiàn)效果

游客一:

游客二

?

轉(zhuǎn)載于:https://www.cnblogs.com/ssyfj/p/9245150.html

總結(jié)

以上是生活随笔為你收集整理的python---websocket的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。