Flask 实现 WebSocket 通讯---群聊和私聊

一、WebSocket介绍

WebSocket是一种在单个TCP连接实现了服务端和客户端进行双向文本或二进制数据通信的一种通信的协议。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

一次请求 - 服务器收到请求 开始和客户端握手 - 保持长连接 - 数据实时 - 连接永远保持
优点:长连接 并且不影响 收发请求
缺点:连接保持,是需要资源的

二、 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>

原文地址:https://www.cnblogs.com/zwq-/p/10457816.html

时间: 2024-07-29 08:18:43

Flask 实现 WebSocket 通讯---群聊和私聊的相关文章

websocket实现群聊和单聊(转)

昨日内容回顾 1.Flask路由 1.endpoint="user" # 反向url地址 2.url_address = url_for("user") 3.methods = ["GET","POST"] # 允许请求进入视图函数的方式 4.redirect_to # 在进入视图函数之前重定向 5./index/<nid> # 动态参数路由 <int:nid> def index(nid) 6.str

Swoole实现基于WebSocket的群聊私聊

本文属于入门级文章,大佬们可以绕过啦.如题,本文会实现一个基于Swoole的websocket聊天室(可以群聊,也可以私聊,具体还需要看数据结构的设计). 搭建Swoole环境 通过包管理工具 # 安装依赖包 $ sudo apt-get install libpcre3 libpcre3-dev # 安装swoole $ pecl install swoole # 添加extension拓展 $ echo extension=swoole.so > /etc/php5/cli/conf.d/s

即时通讯群聊系统1.2

http://code4app.com/ios/535651f2933bf0647d8b570f 介绍: 原创即时通讯系统,拥有和微信一样强大的通讯功能. 具体特色有: 1.首家支持聊天室群聊 2.支持和微信一样的语音聊天,可以显示时长.未读状态,自动轮播未读语音: 3.支持发送图片.表情.GIF动画表情等: 4.数据库分库分表,速度极快,界面细节处理优美,bug极少. 5.另有注册用户.用户列表.加好友.好友列表等功能. 6.实现了发消息后,如接收方不在线,除了离线消息外,会自动推送通知,留了

Java套接字编程实现群聊与私聊[原理版]

简介 运用Java套接字我们几乎可以完成一个网络聊天软件的小产品,本文不涉及UI部分,仅对原理部分用代码演示一下.一个可以多人聊天的小功能,在Linux系统上用telnet亲测可用. 服务器代码 package demo0811.demo3; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.

Android中脱离WebView使用WebSocket实现群聊和推送功能

WebSocket是Web2.0时代的新产物,用于弥补HTTP协议的某些不足,不过他们之间真实的关系是兄弟关系,都是对socket的进一步封装,其目前最直观的表现就是服务器推送和聊天功能.更多知识参考:如何理解 TCP/IP, SPDY, WebSocket 三者之间的关系? 今天的重点是讲如何在Android中脱离WebView使用WebSocket,而不是在Web浏览器使用,如果是在Web浏览器中使用,网上已经太多教程.框架和demo,没必要讲. 到目前为止我个人认为安卓端比较好用的WebS

WebSocket 实现群聊 - 简单测试例子

B/S中一般通信和WebSocket的区别: 在B/S结构的应用中,传统的通信机制是请求-响应的模式,也就是说只有客户端发送请求,服务端才会给出相应的响应(不考虑程序问题或者是其他原因),服务器不能够主动的为浏览器推送消息.但是WebSocket可以实现客户端和服务端的双向通信,其原理就是在客户端和服务器端建立一个通信的管道,来实现客户端和服务器端的双向通信. 通过在写例子的过程中,我的理解是(Java为例-注解方式):服务器端通过注解为方法注册监听事件(项目启动会自动扫描这些注解然后进行装载配

spring websocket 和socketjs实现单聊群聊,广播的消息推送详解

spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 我们知道,传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而

Socket通信 简单实现私聊、群聊(dos命令下)

很久以前的一个Demo,这里服务器只做转发功能,根据ID地址和端口号来标识身份,群聊和私聊只是简单实现, 服务器代码如下: import java.util.*; import java.io.*; import java.net.*; public class Server extends Thread { private static Vector<Socket> vecClient = new Vector<Socket>(); private PrintWriter out

Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)

XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件.网络游戏聊天.Web聊天及Web消息推送.移动设备的消息推送等场景,例如Google的GTalk.<英雄联盟LOL>游戏聊天模块. 由于在Web浏览器上的JavaScript不能直接处理TCP协议,所以XMPP服务器通常会提供BOSH(Bidirectional-streams Over Synchronous HTT