Python获取Websocket接口的数据

Python获取Websocket接口的数据作者:小小明在前面的用Tornado实现web聊天室一文中介绍了python实现websocket的方法,这篇文章将要分享如何用python作为客户端获取websocket接口的数据。前文链接:https://blog.csdn.net/as604049322/article/details/112386560websocket的使用WebSocket是一种在单个TCP/TSL连接上,进行全双工、双向通信的协议。WebSocket可以让客户端与服务器之间的数据交换变得更加简单高效,服务端.

大家好,又见面了,我是你们的朋友全栈君。

作者:小小明

在前面的用Tornado实现web聊天室一文中介绍了python实现websocket的方法,这篇文章将要分享如何用python作为客户端获取websocket接口的数据

前文链接:https://blog.csdn.net/as604049322/article/details/112386560

websocket的使用

WebSocket 是一种在单个 TCP/TSL 连接上,进行全双工、双向通信的协议。WebSocket 可以让客户端与服务器之间的数据交换变得更加简单高效,服务端也可以主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。

WebSocket 可以在连续发送数据的同时不断地接受消息。并不会像 REST 一样,每发送一个请求,要等待服务器完成请求、完全回复之后,再进行下一个请求。”全双工“可以理解为在请求的同时也可以接受消息

websocket与传统http协议的对比:

image-20210124212923278

websocket服务端

首先启动一个简单的websocket服务端用于测试,代码如下:

__author__ = 'xiaoxiaoming'

import datetime
from abc import ABC

import tornado.httpserver
import tornado.ioloop
import tornado.web
from tornado.options import define, options
from tornado.websocket import WebSocketHandler

define("host", default="127.0.0.1", type=str)
define("port", default=8000, type=int)


class ChatHandler(WebSocketHandler, ABC):
    users = set()  # 用来存放在线用户的容器

    def open(self):
        self.users.add(self)  # 建立连接后添加用户到容器中
        for u in self.users:  # 向已在线用户发送消息
            u.write_message(
                f"[{self.request.remote_ip}]-[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]-进入聊天室")

            def on_message(self, message):
                for u in self.users:  # 向在线用户广播消息
                    u.write_message(u"[%s]-[%s]-说:%s" % (
                        self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message))

            def on_close(self):
                self.users.remove(self)  # 用户关闭连接后从容器中移除用户
                for u in self.users:
                    u.write_message(
                        f"[{self.request.remote_ip}]-[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]-离开聊天室")

            def check_origin(self, origin):
                return True  # 允许WebSocket的跨域请求

        if __name__ == '__main__':
            app = tornado.web.Application([
                (r"/", ChatHandler),
            ])
            http_server = tornado.httpserver.HTTPServer(app)
            http_server.listen(options.port)
            print(f"http://{options.host}:{options.port}")
            tornado.ioloop.IOLoop.current().start()

以上代码依赖于tornado,没有安装的需要使用pip安装:

pip install tornado

JavaScript的websocket客户端

websocket的客户端使用JavaScript会非常简单,只需要在游览器后台执行:

var ws = new WebSocket("ws://127.0.0.1:8000/"); // 新建一个ws连接
ws.onmessage = function (evt) { 
     // 收到服务器发送的消息后执行的回调
   console.log(evt.data);  // 接收的消息内容在事件参数evt的data属性中
};

即可在游览器连接上websocket服务端,并在获得消息时自动控制台显示。

执行以下命令可向服务端发送消息:

ws.send("xxxx")

在运行上面的服务端后,我们在游览器中执行以上的JavaScript代码:

image-20210124203721550

服务端只是简单把从客户端收到的所有的消息,加上ip和时间发送给所有的客户端。从上面的结果可以看到我们的测试服务端顺利运行。

Python的websocket同步客户端

那么python中如何实现这样的客户端呢?代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 创建时间:2021/1/24 17:06
__author__ = 'xiaoxiaoming'

import time

import websocket
import _thread


# 在接收到服务器发送消息时调用
def on_message(ws, message):
    print('Received: ' + message)


# 在和服务器建立完成连接时调用
def on_open(ws):
    # 线程运行函数
    def process():
        while True:
            s = input("要发送的内容(quit表示退出):")
            if s == "quit":
                break
            ws.send(s)
            # 休息 0.2 秒先接收服务器回复的消息
            time.sleep(0.2)
        # 关闭 Websocket 的连接
        ws.close()
        print("Websocket closed")

    # 在另一个线程运行 gao() 函数
    _thread.start_new_thread(process, ())


if __name__ == "__main__":
    ws = websocket.WebSocketApp("ws://127.0.0.1:8000/",
                                on_message=on_message,
                                on_open=on_open)

    ws.run_forever()

上面的代码on_open方法启动了一个用于向服务端发送消息的线程。

运行后,也可以顺利看到执行效果:

image-20210124204540219

如果上面已经连接的预览器没有关闭的话也可以收到消息:

image-20210124204819420

需要注意的是这个客户端依赖的包是websocket_client,而不是websocket,如果你缺少这个库,需要执行:

pip -m install websocket_client

来安装。

Python的websockets异步客户端

python支持websocket客户端除了上面这种同步接口,还提供了websockets这种协程实现的异步接口,在我们不需要使用input这种阻塞式方法时,建议直接使用websockets。

需要以下命令来安装:

pip install websockets

测试代码:

__author__ = 'xiaoxiaoming'

import asyncio

import websockets


async def process():
    async with websockets.connect("ws://127.0.0.1:8000/") as ws:
        while True:
            try:
                message = await asyncio.wait_for(ws.recv(), timeout=30)
                print('Received: ' + message)
            except asyncio.TimeoutError as e:
                continue
            except websockets.exceptions.ConnectionClosed as e:
                print('连接已经关闭')
                break

asyncio.run(process())

如果是python3.7以下的版本:

asyncio.run(process())

需要更换为:

loop = asyncio.get_event_loop()
loop.run_until_complete(process())
loop.close()

当然建议直接使用python3.7以上版本的协程。

运行后可以顺利的收到从服务端发来的消息:

image-20210125021724900

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159893.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SpringBoot自动装配原理(简单易懂)

    SpringBoot自动装配原理(简单易懂)1、什么是自动装配自动装配就是把别人(官方)写好的config配置类加载到spring容器,然后根据这个配置类生成一些项目需要的bean对象。(小声逼逼:就像我们自己在项目了写的config配置类一样的,只不过这个是别人写好的,你什么都不用管)2、自动装配的开关在哪里@SpringBootApplication|–@EnableAutoConfiguration|–@Import({AutoConfigurationImportSelector.class})在@Spri

    2025年5月31日
    0
  • 各种门平面图画法_关于CAD各种门怎么画平面图就行?[通俗易懂]

    各种门平面图画法_关于CAD各种门怎么画平面图就行?[通俗易懂]回答:CAD怎么画钢琴平面图CAD怎么画出钢琴的平面图呢?很简单的,有需要的朋友动手试试吧。1、启动中望CAD软件,执行“矩形”命令(rec),绘制1575mmX230mm和1575X50mm的直角矩形。2、执行矩形命令和移动命令(M),绘制出如图所示图形。3、执行移动命令,按[F8]键打开“正交”模式,捕捉上一步绘制的矩形中点,将二部分直角矩形图形组合在一起。4、执行“矩形”命令(rec),绘制…

    2022年5月25日
    58
  • 腾讯云中ssL证书的配置安装

    腾讯云中ssL证书的配置安装

    2021年10月14日
    56
  • http接口开发与调用案例[通俗易懂]

    http接口开发与调用案例[通俗易懂]http接口开发与调用案例

    2022年5月15日
    42
  • WPF-visifire Charts 控件去掉水印

    WPF-visifire Charts 控件去掉水印WPF-visifireCharts控件去掉水印,亲自测试可用!

    2022年7月21日
    11
  • C++之tellg和seekg

    C++之tellg和seekglong pos = file.tellg(); // 得到文件指针当前指向的文件位置。file.seekg(0,ios::beg); //让文件指针定位到文件开头file.seekg(0,ios::end); //让文件指针定位到文件末尾file.seekg(10,ios::cur); //让文件指针从当前位置向文件末方向移动10个字节file.seekg

    2022年6月4日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号