如何用python快速的搭建一个websocket服务器?

准备工作

python:3.9.x

  • python 依赖
    pip3 install asyncio
    pip3 install json
    pip3 install websockets
    pip3 install pyvisa
    pip3 install configparser

目录结构

-case(功能代码模块文件夹)
--OutputPower.py(功能代码,接收到客户端信息,判断进入对应的功能模块)
-websocket(webSocket服务器代码,主要负责维护连接、接收数据、发送数据)
--server.py(服务器代码)
-app.py(程序入口)

代码

server.py
功能包括:
1、建立websocket连接
2、收取客户端信息
3、发送客户端信息

服务器数据处理模块

此处我使用了多线程,主要是想到以后的功能模块交互问题


import asyncio
import websockets
import time
import json
import threading
# 功能模块
from case.OutputPower import OutputPower

# 存储所有的客户端
Clients = []

class Server():
	# 发消息给客户端的回调函数
    async def s(self,msg,websocket=None):
        await self.sendMsg(msg,websocket)
    # 针对不同的信息进行请求,可以考虑json文本
    async def runCase(self,jsonMsg,websocket):
        print('runCase')
        # await OutputPower(jsonMsg,self.s,websocket)
        op = OutputPower()
        await op.run(jsonMsg,self.s,websocket)

    # 每一个客户端链接上来就会进一个循环
    async def echo(self,websocket, path):
        Clients.append(websocket)
        await websocket.send(json.dumps({"type": "handshake"}))
        while True:
            try:
                recv_text = await websocket.recv()
                message = "I got your message: {}".format(recv_text)
                # 直接返回客户端收到的信息
                await websocket.send(message)
                print(message)

                # 分析当前的消息 json格式,跳进功能模块分析
                await self.runCase(jsonMsg='',websocket=websocket)

            except websockets.ConnectionClosed:
                print("ConnectionClosed...", path)  # 链接断开
                Clients.remove(websocket)
                break
            except websockets.InvalidState:
                print("InvalidState...")  # 无效状态
                Clients.remove(websocket)
                break
            except Exception as e:
                print(e)
                Clients.remove(websocket)
                break

    # 发送消息
    async def sendMsg(self,msg,websocket):
        print('sendMsg:',msg)
        if websocket != None:
            await websocket.send(msg)
        else:
            await self.broadcastMsg(msg)
        # 避免被卡线程
        await asyncio.sleep(0.2)

	# 群发消息
    async def broadcastMsg(self,msg):
        for user in Clients:
            await user.send(msg)

    # 启动服务器
    async def runServer(self):
        async with websockets.serve(self.echo, 'localhost', 8888):
            await asyncio.Future()  # run forever

	# 多线程模式,防止阻塞主线程无法做其他事情
    def WebSocketServer(self):
        asyncio.run(self.runServer())

    def startServer(self):
        # 多线程启动,否则会堵塞
        thread = threading.Thread(target=self.WebSocketServer)
        thread.start()
        thread.join()
        print("go!!!")

建立功能模块

做到业务分离(OutputPower.py)

import asyncio

class OutputPower():
    async def run(self,arg,s,websocket):
        # 发送消息方法,单独和请求的客户端发消息
        await s('sssss', websocket)
        # 群发消息
        await s('起来hi')

启动服务

(app.py)


from webSocket.server import Server

if __name__=='__main__':
    s = Server()
    s.startServer()

测试

直接找一个在线的websocket进行连接测试即可,如 http://www.websocket-test.com/

结果如图:

  • 第一个客户端链接
  • 发送:12
  • 服务器返回:I got your message:12
  • 继续返回功能模块的:sssss
  • 返回群发的信息:起来hi
  • 返回群发的信息:起来hi
    第一个客户端链接
  • 第二个客户端链接上去
  • 重复第一个客户端工作,但是第一个客户端多接收到了一个:起来hi
    第二个客户端

怎么解决通信与逻辑分离

于2022.7.13发现一个问题,由于我自己的业务处理时间很长,比如这样的

import asyncio
import time

class OutputPower():
    def __init__(self):
        self._stop = 0

    async def stop(self):
        self._stop = 1
        print('i stop!')

    async def run(self, arg, s, websocket):
        k = 0
        while 1:
            time.sleep(2)
            if self._stop == 1:
                print('i jump out ...')
                break
            print('i am running ...')
            
            k = k+1
            if k== 10:
                break

模拟业务处理:一直要处理20s完成这个业务,但是在开始后发现问题需要立刻停止这个业务,也就是self._stop==1来停止这个业务,如果按照我们上面的设计,收到服务器的消息会就会一直进入 await op.run(jsonMsg,self.s,websocket)业务,直到完成后才会走出这个业务,获得停止的命令,脱离了我们的初衷。
假定我们的协议都是json格式:
开始任务:

{"type": 1}

结束任务

{"type": 2}

那么在页面上的交互逻辑,我直接截图来表达下流程:
交互流程图
步骤如下:
1、websocket建立连接,返回{\type\: \handshake\}
2、开始执行任务,下发:{"type": 1}
3、任务开始执行,返回正在执行的进度:i am running ... 0
4、任务没完成的时候,下发中止任务:{"type": 2}
5、任务中止,输出:stop!

其实这个做法有很多,我在这里就简单的说下我自己的原理:
1、websocket接收数据,缓存到全局变量queue中;
2、server处理增加线程读取这个queue,取出交互协议;
3、再次启动threading去处理该协议内容。

具体的代码可以见下方的测试代码。

测试源码

见:https://download.csdn.net/download/weixin_44635546/85645105

  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
### 回答1: Python可以使用多种库来搭建WebSocket服务器,其中比较常用的是Tornado和WebSocket库。以下是使用Tornado搭建WebSocket服务器的简单示例: 1. 安装Tornado库 ``` pip install tornado ``` 2. 编写WebSocket服务器代码 ```python import tornado.websocket import tornado.web import tornado.ioloop class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): print("WebSocket opened") def on_message(self, message): print("Received message: {}".format(message)) self.write_message("You said: {}".format(message)) def on_close(self): print("WebSocket closed") app = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 3. 运行WebSocket服务器 ``` python server.py ``` 4. 在浏览器中测试WebSocket服务器 在浏览器中打开WebSocket客户端,连接到`ws://localhost:8888/websocket`,即可与WebSocket服务器进行通信。 ### 回答2: Python搭建WebSocket服务器,需要先理解WebSocket的基本概念和相关技术。WebSocket是一种基于TCP协议的全双工通信的网络协议,它允许Web应用程序在客户端与服务器之间建立持久性的连接。在WebSocket建立连接之后,客户端和服务器可以互相发送消息。相比较HTTP协议,WebSocket的实时性更高,特别适合一些需要实时推送数据的应用场景。 在Python中,可以通过Tornado、Twisted等框架来快速搭建WebSocket服务器。下面以Tornado为例,介绍一下如何搭建一个WebSocket服务器。 1. 安装Tornado 首先需要安装Tornado框架,可以通过pip命令进行安装,如下所示: ``` pip install tornado ``` 2. 编写WebSocket服务器代码 下面是一个简单的WebSocket服务器代码示例: ```python import tornado.websocket import tornado.web import tornado.ioloop class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): print('WebSocket连接已打开') def on_message(self, message): print('收到客户端消息:{}'.format(message)) self.write_message('服务器已接收到消息:{}'.format(message)) def on_close(self): print('WebSocket连接已关闭') app = tornado.web.Application([(r'/ws', WebSocketHandler)]) if __name__ == '__main__': app.listen(8888) tornado.ioloop.IOLoop.instance().start() ``` 上述代码中,定义了一个WebSocketHandler类来处理WebSocket连接。在open方法中打印出WebSocket连接已打开的消息,在on_message方法中接收来自客户端的消息,并将消息打印出来并返回一个确认消息到客户端,在on_close方法中打印出WebSocket连接已关闭的消息。在WebSocket服务器启动时,将WebSocketHandler类添加到Tornado应用程序中,并绑定到指定的路由(本例中使用了/ws)上。 3. 运行WebSocket服务器 运行上述代码后,即可启动WebSocket服务器。可以使用任意的WebSocket客户端连接到WebSocket服务器,测试服务器是否工作正常。 总结 通过Tornado框架,可以快速搭建WebSocket服务器,实现实时数据推送等功能。当然,真正的应用场景中,还需要考虑WebSocket的负载均衡,数据安全等一系列问题。因此,在实际的开发过程中,还需要更深入的学习和实践,来构建稳定、可靠的WebSocket服务器。 ### 回答3: WebSocket是一种开放的标准,它提供了一种浏览器和服务器之间进行双向通信的方式。Python是一种强大的编程语言,它具有良好的数据处理和网络编程能力。因此,Python很适合用于搭建WebSocket服务器。 首先,我们需要使用Python的第三方库Tornado或者Twisted等来搭建WebSocket服务器。这里以Tornado为例简要介绍一下搭建步骤。 步骤一:创建一个Tornado应用 我们可以使用Tornado框架的Application类来创建一个应用。在这个应用中,我们需要定义WebSocket路由以及对应的处理函数。 ``` python import tornado.ioloop import tornado.web import tornado.websocket class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): print('WebSocket opened') def on_message(self, message): print('Message received: {}'.format(message)) def on_close(self): print('WebSocket closed') def make_app(): return tornado.web.Application([ (r'/websocket', WebSocketHandler), ]) if __name__ == '__main__': app = make_app() app.listen(8080) tornado.ioloop.IOLoop.current().start() ``` 在上面的代码中,我们定义了一个WebSocketHandler类来处理WebSocket连接。在这个类中,我们重载了WebSocketHandler的三个方法:open、on_message、on_close。这三个方法分别用于处理WebSocket连接建立,消息接收和连接关闭事件。 在make_app函数中,我们定义了路由,并将WebSocketHandler绑定到了路由上。我们通过调用app.listen方法来启动应用,使用IOLoop.current().start函数来启动事件循环。 步骤二:使用JavaScript创建WebSocket客户端 为了与服务器进行通信,我们需要使用JavaScript创建WebSocket客户端。这里我们通过浏览器提供的WebSocket API来创建客户端。 ``` javascript let socket = new WebSocket('ws://localhost:8080/websocket') socket.onopen = function () { console.log('WebSocket opened') } socket.onmessage = function (event) { console.log('Message received:', event.data) } socket.onclose = function () { console.log('WebSocket closed') } ``` 在这段代码中,我们使用浏览器提供的WebSocket构造函数来创建一个WebSocket客户端。我们将服务器的地址ws://localhost:8080/websocket传递给构造函数,这里的地址与在Python Web服务器中创建的WebSocket路由匹配。随后,我们在onopen,onmessage和onclose三个事件处理函数中定义了相应的逻辑。当WebSocket连接建立,消息接收或连接关闭时会分别触发这三个事件,并执行相应的逻辑。 到此,我们已经完成了基本的搭建过程,可以通过浏览器控制台的输出,观察WebSocket连接和消息的收发。 总结 在本文中,我们使用Python的Tornado框架来搭建一个简单的WebSocket服务器,并通过使用浏览器提供的WebSocket API,创建了一个WebSocket客户端。WebSocket服务器提供了浏览器和服务器之间进行实时双向通信的方式,这种通信方式可以用于很多场景,比如实时游戏、即时聊天、在线会议等。通过Python搭建WebSocket服务器,可以使我们更加灵活地开发和管理这些应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

big pineapple

谢谢你的小助力,时间就是金钱。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值