websocket 单点通信,广播通信

        Websocket协议是对http的改进,可以实现client 与 server之间的双向通信; websocket连接一旦建立就始终保持,直到client或server 中断连接,弥补了http无法保持长连接的不足,方便了客户端应用与服务器之间实时通信。

参考:

HTML5 WebSocket | 菜鸟教程

由浅入深介绍 Python Websocket 编程-CSDN博客

应用场景:

        html单点通信

        消息群发

        聊天室功能

一,单点通信

      1,server.py

import asyncio
import websockets
from datetime import datetimeasync def handler(websocket):data = await websocket.recv()reply = f"收到数据:{data}  time: {datetime.now()}"print(reply)await websocket.send(reply)print("Send reply")async def main():async with websockets.serve(handler, "localhost", 9999):await asyncio.Future()  # run foreverif __name__ == "__main__":asyncio.run(main())

        2,python 客户端 client.py

import asyncio
import websockets
import timeasync def ws_client(url):for i in range(1, 40):async with websockets.connect(url) as websocket:await websocket.send("Hello, I'm client 1")response = await websocket.recv()print(response)time.sleep(3)if __name__ == "__main__":asyncio.run(ws_client('ws://127.0.0.1:9999'))

        3,html客户端client.html

<!DOCTYPE HTML>
<html><head><meta charset="utf-8"><title>websocket demo</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"><script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js">		</script><script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script><script type="text/javascript">async function wsClient(url) {for (let i = 1; i <= 40; i++) {const websocket = new WebSocket(url);// Wait for the WebSocket connection to openawait new Promise((resolve, reject) => {websocket.addEventListener('open', () => {resolve();});websocket.addEventListener('error', reject);});// Send a message to the serverwebsocket.send("Hello, I'm client html");// Wait for a response from the serverconst response = await new Promise((resolve) => {websocket.addEventListener('message', (event) => {resolve(event.data);});});// Print the responseconsole.log(response);// Wait for 3 seconds before sending the next messageawait new Promise(resolve => setTimeout(resolve, 1000));// Close the WebSocket connection before the next iterationwebsocket.close();}}                // Call the function with the desired WebSocket URLwsClient('ws://127.0.0.1:9999');</script></head><body></body></html>

        4,启动  :

        python server.py

        python client.py       

         

        打开client.html

二,广播消息

        1,server.py

import asyncio
import websockets
from datetime import datetime,time# 维护一个连接的客户端字典,key为remote_address
connected_clients = {}# 处理连接事件
async def connection_handler(websocket, path):remote_address = websocket.remote_addressprint(f"新连接建立 from {remote_address}")connected_clients[remote_address] = websocket  # 使用remote_address作为key添加到字典中print(f"当前连接数:{len(connected_clients)}")print(f"连接地址:{list(connected_clients.keys())}")try:while True:await message_handler(websocket)except websockets.exceptions.ConnectionClosedOK:print(f"连接已正常关闭 from {remote_address}")print(f"当前连接地址:{list(connected_clients.keys())}")finally:del connected_clients[remote_address]  # 连接关闭时从字典中移除# 处理接收到的消息,并广播出去
async def message_handler(websocket):data = await websocket.recv()reply = f"收到数据:{data}  time: {datetime.now().time()}"print(reply)# 广播消息给所有连接的客户端for client_websocket in connected_clients.values():if client_websocket != websocket:  # 避免给自己发送消息try:await client_websocket.send(reply)except websockets.exceptions.ConnectionClosedError:# 如果某个客户端连接已经关闭,由于字典的key-value特性,无需显式移除print(f"一个连接已关闭,自动从字典中移除")print("Broadcast reply sent")async def main():async with websockets.serve(connection_handler, "localhost", 9999):await asyncio.Future()  # run foreverif __name__ == "__main__":asyncio.run(main())

        2,client.py

import asyncio
import websocketsasync def ws_client(url):async with websockets.connect(url) as websocket:# 发送初始消息await websocket.send("Hello, I'm logging.")# 持续接收消息的循环while True:try:response = await websocket.recv()print(f"Received: {response}")# 可以根据需要处理接收到的消息,比如判断是否需要发送新的消息等except websockets.exceptions.ConnectionClosedError:print("Connection closed by server.")break  # 连接关闭时跳出循环except Exception as e:print(f"An error occurred: {e}")# 根据实际情况决定是否需要重连或进行其他操作# 可以在这里添加延时以控制发送或接收频率,但需谨慎使用以免阻塞事件循环# await asyncio.sleep(1)  # 示例:每秒接收一次消息if __name__ == "__main__":asyncio.run(ws_client('ws://127.0.0.1:9999'))

        3,html

<!DOCTYPE HTML>
<html><head><meta charset="utf-8"><title>websocket demo</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"><script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js">		</script><script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script><script type="text/javascript">var ws; // 在更宽的作用域定义WebSocket实例function WebSocketTest() {if ("WebSocket" in window) {ws = new WebSocket("ws://127.0.0.1:9999/handler"); // 打开WebSocket连接ws.onopen = function () {ws.send("html login");console.log("发送消息(html login)");};ws.onclose = function () {console.log("连接已关闭...");};} else {alert("您的浏览器不支持 WebSocket!");}}// 新增函数,用于发送消息function sendMessage() {if (ws && ws.readyState === WebSocket.OPEN) { // 确保WebSocket已连接且处于OPEN状态var msgInput = document.getElementById("msgInput"); // 假设有一个输入框用于输入消息var msg = msgInput.value || "默认消息内容";ws.send(msg);console.log("发送消息:" + msg);msgInput.value = ""; // 清空输入框} else {console.warn("WebSocket未连接或非OPEN状态,无法发送消息。");}}</script>
</head><body><div class="col-md-6 m-5 p-2" id="div_ws"><a class="btn btn-primary" href="javascript:WebSocketTest()">登录WebSocket</a></div><div class="col-md-6 m-5 p-2" id="div_ws"><a class="btn btn-primary" onclick="sendMessage()" >发送消息</a></div><div class="input-group input-group-lg"><div class="input-group-prepend"><span class="input-group-text" id="inputGroup-sizing-lg">消息</span></div><input type="text"   id="msgInput"  class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg"  placeholder="请输入消息内容..." ></div></body></html>

      4,终端启动服务端 

        python server.py

        5,打开多个终端启动多个客户端

                python client.py   

        6,打开html页面,点击登录WebSocket按钮

        7,输入框输入消息,点击发送消息

三,html 聊天室功能

        1,server.py 

        启动服务端 python server.py

    # reply = f"收到数据:{data}  time: {datetime.now().time()}" 修改响应数据reply = f"{datetime.now().time()} {websocket.remote_address} {data}"

      2,  client.html

<!DOCTYPE HTML>
<html><head><meta charset="utf-8"><title>websocket demo</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"><script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js">		</script><script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script><script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script><script type="text/javascript">var ws; // 在更宽的作用域定义WebSocket实例function WebSocketTest() {if ("WebSocket" in window) {ws = new WebSocket("ws://127.0.0.1:9999/handler"); // 打开WebSocket连接ws.onopen = function () {ws.send("html login");console.log("发送消息(html login)");};ws.onmessage = function (event) { // 添加消息接收处理器var receivedMsg = document.getElementById("receivedMsg"); // 获取用于显示消息的元素receivedMsg.innerHTML += "<br>" + event.data; // 将接收到的消息追加到元素中console.log("接收到消息:" + event.data);};ws.onclose = function () {console.log("连接已关闭...");};} else {alert("您的浏览器不支持 WebSocket!");}}// 新增函数,用于发送消息function sendMessage() {if (ws && ws.readyState === WebSocket.OPEN) { // 确保WebSocket已连接且处于OPEN状态var msgInput = document.getElementById("msgInput"); // 假设有一个输入框用于输入消息var msg = msgInput.value || "默认消息内容";ws.send(msg);console.log("发送消息:" + msg);msgInput.value = ""; // 清空输入框} else {console.warn("WebSocket未连接或非OPEN状态,无法发送消息。");}}</script>
</head><body><div class="col-md-6 m-5 p-2" id="div_ws"><a class="btn btn-primary" href="javascript:WebSocketTest()">登录WebSocket</a></div><div class="col-md-6 m-5 p-2" id="div_ws"><a class="btn btn-primary" onclick="sendMessage()">发送消息</a></div><div class="input-group input-group-lg"><div class="input-group-prepend"><span class="input-group-text" id="inputGroup-sizing-lg">消息</span></div><input type="text" id="msgInput" class="form-control" aria-label="Sizing example input"aria-describedby="inputGroup-sizing-lg" placeholder="请输入消息内容..."></div><div class="col-md-12 m-5 p-2" id="receivedMsg" style="height: 200px;overflow-y: scroll;">消息记录区:</div>
</body></html>

        3,打开3个client.html 客户端,并发送数据

       客户端1,

客户端2,

客户端3,

四,单人聊天功能分析

        1,把获取客户端字典做成api

        2,打开client.html 请求接口获取客户端字典,相当于获取在线好友列表

        3,发送消息,携带通信好友的客户端字典的key值,

        4,服务端从客户端字典查找目标连接,并发送消息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据005-hadoop003-了解MR及Java的简单实现

了解MapReduce MapReduce过程分为两个阶段&#xff1a;map阶段、reduce阶段。每个阶段搜键-值对作为输入和输出。 要执行一个MR任务&#xff0c;需要完成map、reduce函数的代码开发。 Hellow World 【Hadoop权威指南】中的以分析气象数据为例&#xff0c;找到每年的最高气温。…

【网络】gateway 可以提供的一些功能之二 “ 提供Restful服务器路由转发 ”

一、提供web静态资源服务 Web静态资源服务是指通过HTTP协议提供静态文件&#xff08;如HTML、CSS、JavaScript、图片、字体等&#xff09;的服务。这些静态资源文件不经过服务器端处理&#xff0c;直接由客户端&#xff08;如浏览器&#xff09;请求并加载。提供Web静态资源服…

Jenkins持续化集成

优质博文&#xff1a;IT-BLOG-CN 工作过程如下环境准备 开发人员提交代码>jenkins获取代码>调用单元测试>打包>发布 环境准备Jenkins的安装 Tomcat、Maven、Git或Svn、Jdk Jenkins的安装 1、官网下载war &#xff1a;http://Jenkins-ci.org/ 2、tomcat-users.…

NTFS文件权限管理

实验环境 windows server 2016 实验要求 实验步骤 1、 新建文件 2、打开文件夹的属性->安全->高级 3、禁用继承 4、添加组或用户 技术资料&#xff1a; 常用软件&#xff1a; 手机端项目&#xff1a; 电脑端项目&#xff1a; 公司制度&#xff1a; 销售资源&#xff…

【Scala---01】Scala『 Scala简介 | 函数式编程简介 | Scala VS Java | 安装与部署』

文章目录 1. Scala简介2. 函数式编程简介3. Scala VS Java4. 安装与部署 1. Scala简介 Scala是由于Spark的流行而兴起的。Scala是高级语言&#xff0c;Scala底层使用的是Java&#xff0c;可以看做是对Java的进一步封装&#xff0c;更加简洁&#xff0c;代码量是Java的一半。 因…

JAVA读取从WPS在Excel中嵌入的图片资源

读取从WPS在Excel中嵌入的图片资源 引言 许多数据文件中可能包含嵌入式图片&#xff0c;这些图片对于数据分析和可视化非常重要。然而&#xff0c;从 WPS 在 Excel 中读取这些图片可能会有一些技术挑战。在本文中&#xff0c;我将展示如何从 WPS Excel 文件中读取嵌入的图片&am…

海外三大AI图片生成器对比(Stable Diffusion、Midjourney、DALL·E 3)

Stable Diffusion DreamStudio 是Stable Diffusion 的官方网页&#xff0c;价格便宜&#xff0c;对图片的操作性强&#xff0c;但同时编辑页面不太直观&#xff0c;对使用者的要求较高。 与 DALLE 和 Midjourney 不同&#xff0c;Stable Diffusion 是开源的。这也意味着&…

pytorch运行物体检测模型 SSD

物体检测是指根据一张图片包含的多个物体&#xff0c;通过模型分析物体的信息&#xff0c;最终给出图片中物体的位置以及物体的分类名称。物体检测输入的是一张图片&#xff0c;图片上包含多个物体&#xff0c;输出包括 图片中物体的位置和大小的相关信息物体的分类标签名称检…

linux tcpdump的交叉编译以及使用

一、源码下载 官网&#xff1a;点击跳转 二、编译 1、解压 tar -xf libpcap-1.10.4.tar.xz tar -xf tcpdump-4.99.4.tar.xz 2、配置及编译 //libpcap&#xff1a; ./configure --hostarm-linux --targetarm-linux CCarm-linux-gcc --with-pcaplinux --prefix$PWD/build//t…

企业如何保证内部传输文件使用的工具是安全的?

企业内部文件的频繁交换成为了日常运营不可或缺的一环。然而&#xff0c;随着数据量的爆炸式增长和网络攻击手段的日益复杂&#xff0c;内网文件传输的安全隐患也日益凸显&#xff0c;成为企业信息安全的薄弱环节。本文将探讨内网文件传输的安全风险、企业常用的防护措施。 内网…

Django之搭配内网穿透

一&#xff0c;安装coplar 二&#xff0c;开启8087的内网穿透 三&#xff0c;setting.py中加入如下配置&#xff1a; ALLOWED_HOSTS [*]CSRF_TRUSTED_ORIGINS ["https://localhost:8087", "http://localhost:8087"]四&#xff0c;启动项目 五&#xff…

Chrome您的连接不是私密连接 |输入“thisisunsafe”命令绕过警告or添加启动参数

一、输入 thisisunsafe 在当前页面用键盘输入 thisisunsafe &#xff0c;不是在地址栏输入(切记)&#xff0c;就直接敲键盘就行了 因为Chrome不信任这些自签名ssl证书&#xff0c;为了安全起见&#xff0c;直接禁止访问了&#xff0c;thisisunsafe 这个命令&#xff0c;说明你…

STM32之HAL开发——ADC入门介绍

ADC简介 模数转换&#xff0c;即Analog-to-Digital Converter&#xff0c;常称ADC&#xff0c;是指将连续变量的模拟信号转换为离散的数字信号的器件&#xff0c;比如将模温度感器产生的电信号转为控制芯片能处理的数字信号0101&#xff0c;这样ADC就建立了模拟世界的传感器和…

第4篇:创建Nios II工程之Hello_World<三>

Q&#xff1a;接着我们再来完成Nios II软件工程设计部分。 A&#xff1a;从Quartus Tools选择Nios II Software Build Tools for Eclipse&#xff0c;打开Nios II SBT软件&#xff0c;Workspace指定到hello_world工程的software文件夹路径&#xff1b;再从File-->New-->…

Linux命令大全 以及搭建hadoop

Liunx系统目录 ├── bin -> usr/bin # 用于存放二进制命令 ├── boot # 内核及引导系统程序所在的目录 ├── dev # 所有设备文件的目录&#xff08;如磁盘、光驱等&#xff09; ├── etc # 配置文件默认路径、服务启动命令存放目录 ├── home # 用户家目录&#…

上位机图像处理和嵌入式模块部署(树莓派4b设置ftp下载)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 作为一个开发板&#xff0c;最好支持ftp下载&#xff0c;这样文件的上传和下载都会比较方便。虽然目前为止&#xff0c;利用mobaxterm和ssh也能实现…

ObjectARX特性面板OPM添加动态属性

参考资料 AutoCAD与动态属性PDF文档 https://www.progdomain.com/584/ObjectARX2016 OPM面板全攻略 https://blog.csdn.net/jfmyes/article/details/121392332 准备工作——正确安装ARX和Wizards ARX和VS的版本对应、ObjectArx(2010~2020)工程创建、类添加及错误处理 https:…

C语言内存函数及模拟实现

之前写的字符函数都只针对字符串&#xff0c;而内存函数是针对内存的&#xff0c;不在乎内存里面是什么。 目录 memcpy函数介绍模拟实现 memmove函数介绍模拟实现 memset函数介绍 memcmp memcpy 函数介绍 void * memcpy ( void * destination, const void * source, size_t n…

什么是ar.exe?

2024年4月28日&#xff0c;周日上午 ar.exe 是一个用于创建、修改以及提取静态库&#xff08;archive&#xff09;文件的工具。静态库是一种包含已编译目标文件的归档文件&#xff0c;通常用于代码的静态链接。ar 工具通常与 C/C 编译器一起使用&#xff0c;用于创建和管理静态…

《从Paxos到Zookeeper》——第四、七章:基本概念及原理

目录 第四章 Zookeeper与Paxos 4.1 Zk是什么 4.1.1 Zk特性 4.1.2 Zk基本概念 4.1.2.1 集群角色(Follower, Leader, Observer) 4.1.2.2 数据模型 4.1.2.3 ZNode(数据节点) 4.1.2.4 Session(会话) 4.1.2.5 ACL&#xff08;Access Control Lists&#xff09; 4.1.2.6 Watcher(事件…