专栏首页Python 学习day119-Flask的websocket使用
原创

day119-Flask的websocket使用

# 着重注意前段 websocket 实例的函数内作用域问题

1.websocket之群聊

1.1后端代码

import json
from pprint import pprint

from flask import Flask, request
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket  # 做语法提示使用

app = Flask(__name__)

# websocket 的列表
user_socket_dict = {}


@app.route('/my_ws/<nick_name>')
def ws(nick_name):
    print(nick_name + '连接服务器')
    # 记录客户端信息
    user_socket = request.environ.get('wsgi.websocket')  # type: WebSocket

    if nick_name not in user_socket_dict:
        user_socket_dict[nick_name] = user_socket
    while 1:
        # 收消息
        msg = user_socket.receive()
        for socket in user_socket_dict.values():
            # 给每一个 socket 对象 send 消息
            socket.send('来自用户{}-->{}'.format(nick_name, msg))


if __name__ == '__main__':
    # 跟实际的 app 的原型方式不一样
    print('服务启动')
    http_service = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler)
    http_service.serve_forever()

1.2前段代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<h1>websocket群聊实例</h1>
<hr id="hello">
<hr>
<p>
    我的昵称: <input type="text" id="nickName">
    <button id="connect">连接服务器</button>
</p>
<p>
    编辑内容: <input type="text" id="chatContent">
    <button id="submitContent">点击提交</button>
</p>
</body>
<script>
    // 建立连接
    document.getElementById('connect').onclick = function () {
        let nickName = document.getElementById('nickName').value
        // 定义全局新连接
        ws = new WebSocket('ws://127.0.0.1:5000/my_ws/' + nickName)

        // 注意 ws 的作用域,在建立连接之后监听
        ws.onmessage = function (data) {
            // 监听获取后端的 send,组装进代码块
            let msg = data.data
            let htmlBlock = document.createElement("p")
            htmlBlock.innerText = msg
            document.getElementById('hello').appendChild(htmlBlock)
        }
    }

    // 提交内容
    document.getElementById('submitContent').onclick = function () {
        let content = document.getElementById('chatContent').value
        console.log(content)
        // 提交内容
        // 此时的 ws 已经被建立,所有可以全局函数内使用
        ws.send(content)
    }

</script>
</html>

2.websocket之指定好友聊天

2.1后端代码

import json
from pprint import pprint

from flask import Flask, request
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket  # 做语法提示使用

app = Flask(__name__)

# websocket 的列表
user_socket_dict = {}


@app.route('/my_ws/<nick_name>')
def ws(nick_name):
    # print(name + '连接服务器')
    # 记录客户端信息
    user_socket = request.environ.get('wsgi.websocket')  # type: WebSocket

    if nick_name not in user_socket_dict:
        user_socket_dict[nick_name] = user_socket
    print(user_socket_dict)
    while 1:
        # 收消息
        # 反序列化字符串
        msg = json.loads(user_socket.receive())
        # 取到好友名字传递信息
        friend = msg['friend_name']
        content = msg['content']
        send_content = '来自用户{}-->{}'.format(nick_name, content)
        # 给好友发一份
        user_socket_dict[friend].send(send_content)
        # 给自己也发一份
        user_socket.send(send_content)


if __name__ == '__main__':
    # 跟实际的 app 的原型方式不一样
    print('服务启动')
    http_service = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler)
    http_service.serve_forever()

2.2前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<h1>websocket一对一实例</h1>
<hr id="hello">
<hr>
<p>
    我的昵称: <input type="text" id="nickName">
    <button id="connect">连接服务器</button>
</p>
<p>
    发给好友: <input type="text" id="friendName">
</p>
<p>
    编辑内容: <input type="text" id="chatContent">
    <button id="submitContent">点击提交</button>
</p>
</body>
<script>
    // 建立连接
    document.getElementById('connect').onclick = function () {
        let name = document.getElementById('nickName').value
        // 定义全局新连接
        ws = new WebSocket('ws://127.0.0.1:5000/my_ws/' + name)

        // 定义完连接直接监听后端数据
        ws.onmessage = function (data) {
            // 监听获取后端的 send,组装进代码块
            let msg = data.data
            let htmlBlock = document.createElement("p")
            console.log('后端 msg', msg)
            htmlBlock.innerText = msg
            document.getElementById('hello').appendChild(htmlBlock)
        }

        // 提交聊天数据
        document.getElementById('submitContent').onclick = function () {
            // 获取想要提交的好友
            let friendName = document.getElementById('friendName').value
            // 获取编辑的内容
            let content = document.getElementById('chatContent').value

            let postMsg = {'friend_name': friendName, 'content': content}
            // 提交内容
            // 此时的 ws 已经被建立,所有可以全局函数内使用
            ws.send(JSON.stringify(postMsg))
            console.log(JSON.stringify(postMsg))
        }
    }

</script>
</html>

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SALalchemy增删改查

    少年包青菜
  • day100-Exception继承定义错误信息&结算接口&结算数据结构

    少年包青菜
  • 数据库-part3-pymysql模块操作数数据库

    少年包青菜
  • 论文笔记系列-Efficient Neural Architecture Search via Parameter Sharing

    本文提出超越神经架构搜索(NAS)的高效神经架构搜索(ENAS),这是一种经济的自动化模型设计方法,通过强制所有子模型共享权重从而提升了NAS的效率,克服了NA...

    marsggbo
  • [接口测试 - http.client篇] 17 http.client之入门级接口测试框架

    概述 在上文《[接口测试 - http.client篇] 16 基于http.client之POM实战一下》分享了如何应用POM模式来进行接口测试。 因时间等因...

    苦叶子
  • Spring Boot(六):如何优雅的使用 Mybatis

    这两天启动了一个新项目因为项目组成员一直都使用的是 Mybatis,虽然个人比较喜欢 Jpa 这种极简的模式,但是为了项目保持统一性技术选型还是定了 Mybat...

    纯洁的微笑
  • 美国国防部“黑了空军(Hack the Air Force)”漏洞奖励计划即将启动,仍由HackerOne运营

    大数据文摘
  • 解决laravel5中auth用户登录其他页面获取不到登录信息的问题

    首先创建user表,里面有:id, name, password,remember_token等字段。

    砸漏
  • linux入门(基础命令篇)

    bering
  • Hadoop-2.6.0为基础的Hive安装

    hive服务端安装好之后,服务端如何连接使用? * 服务端需要启动hive metastore服务,客户端才能远程使用hive元信息

    字母哥博客

扫码关注云+社区

领取腾讯云代金券