flask+geventwebsocket实现群体、单体聊天室

思路:

  1. 将websocket请求以 {name:socket} 存储到字典或mongodb,redis中;
  2. while True建立通信循环
  3. socket.receive()收消息
  4. socket.send()发消息
  5. json模块序列化返回的数据
  6. 服务端根据客户端消息判断聊天类型,并选择socket对象
  7. 客户端根据服务端的消息将信息展示在不同区域

代码

python:

from flask import Flask
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
from flask import request
from geventwebsocket.websocket import WebSocket  # 语法提示
from flask import render_template
from json import loads, dumps

app = Flask(__name__, template_folder='./templates')

socket_dic = {
     

}


@app.route('/ws/')
def ws(username):
    sock = request.environ.get('wsgi.websocket', None)  # type:WebSocket
    # 不是ws协议上来的协议取不到wsgi.websocket

    if not sock:
        return '请使用ws链接'
    socket_dic[username] = sock
    print(socket_dic)
    while True:
        msg = sock.receive()
        if msg:
            msg_dic = loads(msg)
            to = msg_dic.get('to')
            data = msg_dic.get('data')
            host = msg_dic.get('host')
            if to:
                if to in socket_dic.keys():
                    socket_dic[to].send(dumps({
     'host': host, 'data': data, 'to': to}))
                    sock.send(dumps({
     'host': host, 'data': data, 'to': to}))
                else:
                    continue
            else:
                for v in socket_dic.values():
                    v.send(dumps({
     'host': host, 'data': data, 'to': to}))


@app.route('/')
def login():
    return render_template('client.html')


if __name__ == '__main__':
    http_server = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler)
    http_server.serve_forever()

html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>clienttitle>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js">script>
    <script src="https://use.fontawesome.com/ada3f762c2.js">script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
head>
<body>

{# 登录模块 #}
<div id="login" class="col-md-4 col-md-offset-4">
    <h1 class="text-center">欢迎登录九聊!h1>
    <p>
        <span class="text text-info" style="font-size: 20px">username:span><input type="text" id="username" class="form-control">
    p>
    <button class="btn btn-success text-center" id="enter">进入聊天室button>
div>

{# 聊天信息显示模块 #}
<div id="home">
div>

body>
<script>
    let web=null;
    let loginEle=$('#login')
    let sendEle=$('#home')
    let enterEle=$('#enter').click(function (){
       
        let username=$('#username').val().trim();
        web=new WebSocket('ws://127.0.0.1:5000/ws/'+username)
        loginEle.remove()
        web.onopen=function (){
       
            alert(username+'欢迎来到久聊!')
        }
        sendEle.html(
            `
            

聊天室


公共消息
私人消息
`
) $('#btn').click(function (){ let toEle=$('#to') let textEle=$('#text') let toName=toEle.val().trim() let data=textEle.val() web.send(JSON.stringify({ "to":toName,"data":data,'host':username})) textEle.val('') }) web.onmessage=function (msg){ let s=msg.data; let res=JSON.parse(s) let p = document.createElement('p'); if (res.to) { p.innerText=res.host+'->'+res.to+':'+res.data document.getElementById('person').appendChild(p); } else { p.innerText=res.host+':'+res.data document.getElementById('content').appendChild(p); } } })
script> html>

效果演示

flask+geventwebsocket实现群体、单体聊天室_第1张图片flask+geventwebsocket实现群体、单体聊天室_第2张图片
flask+geventwebsocket实现群体、单体聊天室_第3张图片
flask+geventwebsocket实现群体、单体聊天室_第4张图片

你可能感兴趣的:(python,flask,websocket,python)