Flask 实现 WebSocket 通讯---群聊和私聊
一、WebSocket介绍
WebSocket是一种在单个TCP连接实现了服务端和客户端进行双向文本或二进制数据通信的一种通信的协议。
一次请求 - 服务器收到请求 开始和客户端握手 - 保持长连接 - 数据实时 - 连接永远保持
优点:长连接 并且不影响 收发请求
缺点:连接保持,是需要资源的
二、 Flask 实现 WebSocket的基本用法
from geventwebsocket.server import WSGIServer # 我要WSGI为我提供服务
from geventwebsocket.handler import WebSocketHandler # WSGI 遇到 WS协议的时候,处理方式
from geventwebsocket.websocket import WebSocket # 语法提示
# 基于 Flask + geventwebsocket
from flask import Flask,request,render_template app = Flask(__name__) if __name__ == '__main__':
# app.run()
# 启动服务
http_serv = WSGIServer(("0.0.0.0", 7856),application=app, handler_class=WebSocketHandler)
http_serv.serve_forever()
三、Python + Flask 实现 WebSocket 通讯
1、实现简单群聊
后端代码 my_ws_ql.py:
from geventwebsocket.server import WSGIServer # 我要WSGI为我提供服务
from geventwebsocket.handler import WebSocketHandler # WSGI 遇到 WS协议的时候,处理方式
from geventwebsocket.websocket import WebSocket # 语法提示
# 基于 Flask + geventwebsocket
from flask import Flask,request,render_template app = Flask(__name__) # 存储访问的连接
user_socket_list = [] @app.route('/ws')
def my_ws_func():
user_socket = request.environ.get('wsgi.websocket') # type:WebSocket
#
user_socket_list.append(user_socket)
# web + socket
print(user_socket)
# 浏览器发起的http请求 None
# 用前端js发送的ws请求 <geventwebsocket.websocket.WebSocket object at 0x0000000003ADF2B8>
while 1:
msg = user_socket.receive() # 等待接收客户端发送过来的消息
for i in user_socket_list:
# # 剔除自己的连接(不给自己推送自己发的消息,这样自己就看不到自己发的消息只能看到其他人发的)
# if i == user_socket:
# continue
# 当循环到死链接时会抛出异常,这里捕捉一下,出现异常直接continue
try:
# 给其他连接推送消息
i.send(msg)
except:
continue
print(msg) @app.route('/group_chat')
def group_chat():
return render_template('group_chat.html') if __name__ == '__main__':
# app.run()
http_serv = WSGIServer(("0.0.0.0", 7856),application=app, handler_class=WebSocketHandler)
http_serv.serve_forever()
前端模板代码 group_chat.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>发送消息>>> <input type="text" id="message"><button onclick="send_msg()">发送</button></p>
<div id="message_list" style="width:500px;"> </div>
</body>
<script type="text/javascript">
var ws = new WebSocket("ws://192.168.15.37:7856/ws");
// 当ws 收到消息时执行 onmessage 属性
ws.onmessage = function (event) {
console.log(event.data);
// 创建p标签,将接收到的消息加入p标签中
var ptag = document.createElement("p");
ptag.innerText = event.data;
// 将创建的p标签添加到页面中
var divtag = document.getElementById('message_list');
divtag.appendChild(ptag);
}; function send_msg() {
// 发送消息的函数
var msg = document.getElementById('message').value;
ws.send(msg);
}
</script>
</html>
2.实现简单的单独通讯
my_ws.py
import json from geventwebsocket.server import WSGIServer # 我要WSGI为我提供服务
from geventwebsocket.handler import WebSocketHandler # WSGI 遇到 WS协议的时候,处理方式
from geventwebsocket.websocket import WebSocket # 语法提示
from flask import Flask, render_template, request app = Flask(__name__) # user_socket_dict = {"ZWQ":<geventwebsocket.websocket.WebSocket object at 0x000002699374A730>,
# "清风徐来":<geventwebsocket.websocket.WebSocket object at 0x000002699374A5F8>} user_socket_dict = {} @app.route('/ws/<nickname>')
def my_ws_func(nickname): user_socket = request.environ.get("wsgi.websocket") # type: WebSocket
user_socket_dict[nickname] = user_socket
print(len(user_socket_dict), user_socket_dict)
# web + socket
# print(user_socket)
while 1:
msg = user_socket.receive() # 等待接收客户端发送过来的消息
print(msg)
msg = json.loads(msg) # Dict
"""
Dict
{
to_user:ZWQ
from_user:清风徐来
message: "我是清风徐来发给ZWQ的一条消息"
}
"""
to_user_socket = user_socket_dict.get(msg.get("to_user")) # 获取发送地址
msg_json = json.dumps(msg)
to_user_socket.send(msg_json) @app.route('/private_chat')
def privatre_chat():
return render_template('private_chat.html') if __name__ == '__main__':
http_ws = WSGIServer(("0.0.0.0",7856), application=app,handler_class=WebSocketHandler)
http_ws.serve_forever()
模板代码 private_chat.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>登录名 :<input type="text" id="nick"> <button onclick="login()">登录</button></p>
<p> 给 <input type="text" id="to_user"> </p>
<p> 发送消息: <input type="text" id="message"><button onclick="send_msg()">发送</button> </p>
<div id="message_list" style="width: 500px">
</div>> </body>
<script type="text/javascript">
var ws = null; function send_msg() {
var msg = document.getElementById('message').value;
var to_user = document.getElementById('to_user').value;
var nick = document.getElementById('nick').value;
var msg_obj = {
to_user:to_user,
from_user:nick,
msg:msg
};
var msg_json = JSON.stringify(msg_obj);
ws.send(msg_json);
} function login() {
var nick = document.getElementById("nick").value;
ws = new WebSocket("ws://192.168.15.33:7856/ws/"+nick);
// 收到消息执行onmessage属性
ws.onmessage = function (event) {
data_obj = JSON.parse(event.data); // 将JSON数据反序列化
var ptag = document.createElement('p');
ptag.innerText = data_obj.from_user + ":" + data_obj.msg;
var divtag = document.getElementById('message_list');
divtag.appendChild(ptag);
}
} </script>
</html>
Flask 实现 WebSocket 通讯---群聊和私聊的更多相关文章
- websocket实现群聊和单聊(转)
昨日内容回顾 1.Flask路由 1.endpoint="user" # 反向url地址 2.url_address = url_for("user") 3.m ...
- 一例完整的websocket实现群聊demo
前言 业余我都会花一些时间在tcp.http和websocket等领域的学习,现在觉得有点收获,所以把一个基于websocket的群聊功能的例子提供给大家玩玩.当然这是一个很完整的例子,包括webso ...
- Flask+WebSocket实现群聊与单聊功能
在开始我们的程序代码之前,先来了解一下相关的基础知识: 1.什么是websocket? (1)WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议.WebSocket ...
- Websocket实现群聊、单聊
Websocket 使用的第三方模块:gevent-websocket 群聊 ws群聊.py中的内容 from flask import Flask, request, render_template ...
- websocket实现群聊
server # @File: 群聊 from flask import Flask, render_template, request from geventwebsocket.handler im ...
- Flask实现简单的群聊和单聊
Flask是使用python写的一个简单轻量级的框架,今天我们使用Flask实现一个简单的单聊和群聊功能 . 主要思路 : 前端登录聊天室,聊天室信息包含用户的登录信息,相当于一个登录功能,会把这个信 ...
- Android中脱离WebView使用WebSocket实现群聊和推送功能
WebSocket是Web2.0时代的新产物,用于弥补HTTP协议的某些不足,不过他们之间真实的关系是兄弟关系,都是对socket的进一步封装,其目前最直观的表现就是服务器推送和聊天功能.更多知识参考 ...
- WebSocket群聊与单聊
一 . WebSocket实现群聊 py文件代码 # py文件 from flask import Flask, render_template, request from geventwebsock ...
- spring websocket 和socketjs实现单聊群聊,广播的消息推送详解
spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随 ...
随机推荐
- 201621123008 《Java程序设计》第五周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口,内部类. 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用常 ...
- apache的错误日志分析
- send发送一次buffer
发送的字符串后面添加:\r\n 结束标志 否则发送1024或者程序接收默认的字节数 #include <stdio.h> #include <stdlib.h> #includ ...
- C#的一些方法读程序转c++
1.Array.Copypublic static void Copy( Array sourceArray, int sourceIndex, Array destinationArray, int ...
- 《JavaScript高级程序设计》笔记
1. 当在函数内部定义了其他函数时,就创建了闭包.闭包有权访问包含函数内部的所有变量. 2. 闭包可以分隔变量空间,不会占用全局空间而造成相互间的干拢.使用闭包可以在JavaScript中模仿块级作用 ...
- Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
解决方法: <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-m ...
- NAND FLASH和LCD电路图
- Android Activity切换(跳转)时出现黑屏的解决方法
在两个Activity跳转时,由于第二个Activity在启动时加载了较多数据,就会在启动之前出现一个短暂的黑屏时间,解决这个问题比较简单的处理方法是将第二个Activity的主题设置成透明的,这样在 ...
- "我们分手吧。"女的对男的说。 "为什么呢?亲爱的,你不要我了么?" "因为你幼稚。"女的坚定地语气回答道,然后转身准备走。 男的上前踩住女的影子,然后说...
1."我们分手吧."女的对男的说. "为什么呢?亲爱的,你不要我了么?" "因为你幼稚."女的坚定地语气回答道,然后转身准备走. 男的上前踩 ...
- 2018.09.11 bzoj2208: [Jsoi2010]连通数(bitset+floyd)
传送门 听说正解是缩点+dfs? 直接bitset优化floyd传递闭包就行了.(尽管时间复杂度是假的O(n3/32)" role="presentation" styl ...