群聊無昵稱
原生js代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>群聊</title> </head> <body> <p> <input type="text" id="content"> <button onclick="send_msg()">發送</button> <!--給按鈕綁定點擊事件--> </p> <div id="chat_list"> </div> </body> <script type="application/javascript"> var ws = new WebSocket("ws://192.168.16.42:9527/my_socket"); // 監聽后端發來的消息,ws.onmessage起到監聽的作用,只要有消息過來函數會自動執行 ws.onmessage = function (eventMessage) { console.log(eventMessage.data); // 獲取后端發來的消息 var p = document.createElement("p"); p.innerText = eventMessage.data; document.getElementById("chat_list").appendChild(p); // 將消息內容添加到div內 }; // 將我們輸入的內容發送給后端 function send_msg() { var content = document.getElementById("content").value; ws.send(content); }; </script> </html>
后端邏輯代碼
# -*- coding: utf-8 -*- # @Time : 2019/7/15 16:42 from flask import render_template,request,Flask from geventwebsocket.handler import WebSocketHandler # 提供WS協議處理 from geventwebsocket.server import WSGIServer # 承載服務 from geventwebsocket.websocket import WebSocket # 語法提示 app = Flask(__name__) user_socket_list = [] @app.route("/my_socket") def my_socket(): # 獲取當前客戶端與服務器的Socket連接 user_socket = request.environ.get("wsgi.websocket") # type:WebSocket if user_socket: user_socket_list.append(user_socket) print(len(user_socket_list),user_socket_list) # 1 [<geventwebsocket.websocket.WebSocket object at 0x000001D0D70E1458>] # print(user_socket,"OK 連接已經建立好了,接下來發消息吧") while 1: # 等待前端將消息發送過來 msg = user_socket.receive() print(msg) for usocket in user_socket_list: try: usocket.send(msg) except: continue @app.route("/qunliao") def gc(): return render_template("qunliao.html") if __name__ == '__main__': http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) # 這種啟動方式和app.run()不沖突,該啟動方式發什么請求都可以接受到 http_serv.serve_forever()
流程
1、用戶在網頁請求http://192.168.16.42:9527/qunliao 2、請求/qunliao這個路由走后端對應的視圖函數gc返回qunliao.html這個頁面, 3、頁面在加載的過程中走到script代碼時建立WebSocket連接請求ws://192.168.16.42:9527/my_socket, 4、ws://192.168.16.42:9527/my_socket請求走后端對應的視圖函數,獲取當前客戶端與服務器的socket連接對象,調用該對象的receive方法,等待前端發來消息, 5、前端我們通過給input框綁定點擊事件,獲取用戶輸入的內容發送給服務器; 6、后端將前端發來的消息在發送給前端; 7、前端通過ws.onmessage這個事件監聽着后端過來的消息,只要有消息就會自動觸發函數執行並獲取數據;
第一步是瀏覽器向/quliao這個路徑發起請求:
jQuery

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>群聊</title> </head> <body> <p> <input type="text" id="content"> <button id="send_msg" >發送</button> <!--給按鈕綁定點擊事件--> </p> <div id="chat_list"> </div> </body> <script src="/static/jquery-3.4.1.js"></script> <script type="application/javascript"> var ws = new WebSocket("ws://192.168.16.42:9527/my_socket"); // 監聽后端發來的消息,ws.onmessage起到監聽的作用,只要有消息過來函數會自動執行 ws.onmessage = function (eventMessage) { console.log(eventMessage.data); // 獲取后端發來的消息 var p = document.createElement("p"); // 創建一個p標簽 p.innerText = eventMessage.data; // 將后端發來的數據添加到p標簽內 $("#chat_list").append(p) // 將p標簽添加到div內 }; // 將我們輸入的內容發送給后端 $("#send_msg").click(function () { var content = $("#content").val(); ws.send(content); }) </script> </html>

from flask import render_template,request,Flask from geventwebsocket.handler import WebSocketHandler # 提供WS協議處理 from geventwebsocket.server import WSGIServer # 承載服務 from geventwebsocket.websocket import WebSocket # 語法提示 app = Flask(__name__,static_folder="statics",static_url_path="/static") # 獲取靜態文件 user_socket_list = [] @app.route("/my_socket") def my_socket(): # 獲取當前客戶端與服務器的Socket連接 user_socket = request.environ.get("wsgi.websocket") # type:WebSocket if user_socket: user_socket_list.append(user_socket) print(len(user_socket_list),user_socket_list) # 1 [<geventwebsocket.websocket.WebSocket object at 0x000001D0D70E1458>] # print(user_socket,"OK 連接已經建立好了,接下來發消息吧") while 1: # 等待前端將消息發送過來 msg = user_socket.receive() print(msg) for usocket in user_socket_list: try: usocket.send(msg) except: continue @app.route("/qunliao") def gc(): return render_template("qunliao.html") if __name__ == '__main__': http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()
帶群昵稱的群聊
通過動態路由參數獲取前端傳過來的用戶名

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>群聊</title> </head> <body> <input type="text" id="username"> <button id="login">登錄</button> <p> <input type="text" id="content"> <button id="send_msg" >發送</button> <!--給按鈕綁定點擊事件--> </p> <div id="chat_list"> </div> </body> <script src="/static/jquery-3.4.1.js"></script> <script type="application/javascript"> var ws = null; // 創建全局變量,ws多處使用 $("#login").click(function () { var username = $("#username").val(); console.log(username); // 創建一個websocket對象,建立websocket連接,更改了全局的ws,將用戶名拼接上 ws = new WebSocket("ws://192.168.16.42:9527/my_socket/" + username); // 監聽后端發來的消息,ws.onmessage起到監聽的作用,只要有消息過來函數會自動執行 ws.onmessage = function (eventMessage) { console.log(eventMessage.data); // 獲取后端發來的消息 var str_obj = JSON.parse(eventMessage.data); // 反序列化,因為我們在發送給后端的時候是json var p = document.createElement("p"); // 創建一個p標簽 $(p).text(str_obj.from_user +":"+str_obj.chat); // 將dom對象轉換成jQuery對象,將后端發來的數據添加到p標簽內 $("#chat_list").append(p) // 將p標簽添加到div內 }; }); // 將我們輸入的內容發送給后端 $("#send_msg").click(function () { var content = $("#content").val(); var username = $("#username").val(); // 將要發送的內容封裝成自定義對象 var sendStr = { from_user:username, chat:content }; console.log(sendStr); // 序列化后發送給后端 ws.send(JSON.stringify(sendStr)); }); </script> </html>

from flask import render_template,request,Flask from geventwebsocket.handler import WebSocketHandler # 提供WS協議處理 from geventwebsocket.server import WSGIServer # 承載服務 from geventwebsocket.websocket import WebSocket # 語法提示 app = Flask(__name__,static_folder="statics",static_url_path="/static") user_socket_dict = {} # 建立websocket連接時,前端將名字發送過來了 @app.route("/my_socket/<username>") def my_socket(username): # 獲取當前客戶端與服務器的Socket連接 user_socket = request.environ.get("wsgi.websocket") # type:WebSocket if user_socket: # 以名字為key,連接對象為value添加到字典中 user_socket_dict[username] = user_socket while 1: # 等待前端將消息發送過來,此時是json數據 msg = user_socket.receive() for usocket in user_socket_dict.values(): try: # 將收到的信息在發送給所有與服務器建立連接的前端 usocket.send(msg) except: continue @app.route("/qunliao") def gc(): return render_template("qunliaonicheng.html") if __name__ == '__main__': http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()
效果:
websocket實現私聊

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>群聊</title> </head> <body> 我的昵稱:<input type="text" id="username"> <button id="login">登錄</button> <p> 給<input type="text" id="to_user">發送 <input type="text" id="content"> <button id="send_msg" >發送</button> <!--給按鈕綁定點擊事件--> </p> <div id="chat_list"> </div> </body> <script src="/static/jquery-3.4.1.js"></script> <script type="application/javascript"> var ws = null; // 創建全局變量,ws多處使用 $("#login").click(function () { var username = $("#username").val(); console.log(username); // 創建一個websocket對象,建立websocket連接,更改了全局的ws,將用戶名拼接上 ws = new WebSocket("ws://192.168.16.42:9527/my_socket/" + username); // 監聽后端發來的消息,ws.onmessage起到監聽的作用,只要有消息過來函數會自動執行 ws.onmessage = function (eventMessage) { console.log(eventMessage.data); // 獲取后端發來的消息 var str_obj = JSON.parse(eventMessage.data); // 反序列化,因為我們在發送給后端的時候是json var p = document.createElement("p"); // 創建一個p標簽 $(p).text(str_obj.from_user +":"+str_obj.chat); // 將dom對象轉換成jQuery對象,將后端發來的數據添加到p標簽內 $("#chat_list").append(p) // 將p標簽添加到div內 }; }); // 將我們輸入的內容發送給后端 $("#send_msg").click(function () { var content = $("#content").val(); var username = $("#username").val(); var to_user = $("#to_user").val(); // 將要發送的內容封裝成自定義對象 var sendStr = { from_user:username, chat:content, to_user:to_user, }; console.log(sendStr); // 序列化后發送給后端 ws.send(JSON.stringify(sendStr)); }); </script> </html>

import json from flask import render_template,request,Flask from geventwebsocket.handler import WebSocketHandler # 提供WS協議處理 from geventwebsocket.server import WSGIServer # 承載服務 from geventwebsocket.websocket import WebSocket # 語法提示 app = Flask(__name__,static_folder="statics",static_url_path="/static") user_socket_dict = {} # 建立websocket連接時,前端將名字發送過來了 @app.route("/my_socket/<username>") def my_socket(username): # 獲取當前客戶端與服務器的Socket連接 user_socket = request.environ.get("wsgi.websocket") # type:WebSocket if user_socket: # 以名字為key,連接對象為value添加到字典中 user_socket_dict[username] = user_socket while 1: # 等待前端將消息發送過來,此時是json數據 msg = user_socket.receive() print(msg) # {"from_user":"wuchao","chat":"123","to_user":"xiaohei"} # 反序列化 msg_dict = json.loads(msg) # 查找字典中前端要發送信息給那個人的名字 to_username = msg_dict.get("to_user") # 獲取目標人物的連接地址 to_user_socket = user_socket_dict.get(to_username) # 將信息發送給目標人物 to_user_socket.send(msg) @app.route("/siliao") def gc(): return render_template("siliao.html") if __name__ == '__main__': http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()
效果