sanic + webSocket:股票实时行情推送服务实现
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
-
推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~
-
专栏导航
- Python系列: Python面试题合集,剑指大厂
- Git系列: Git操作技巧
- GO系列: 记录博主学习GO语言的笔记,该笔记专栏尽量写的试用所有入门GO语言的初学者
- 数据库系列: 详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
- 运维系列: 总结好用的命令,高效开发
- 算法与数据结构系列: 总结数据结构和算法,不同类型针对性训练,提升编程思维
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
💖The Start💖点点关注,收藏不迷路💖📒文章目录
- 1、Sanic WebSocket 实现股票实时推送服务
- 1.1. 设置 Sanic WebSocket 服务端
- 1.2. 创建 HTML 客户端代码
- 2. 实现客户端与服务端的交互
- 3. 总结
1、Sanic WebSocket 实现股票实时推送服务
在本文中,我们将详细介绍如何使用 Sanic 框架来实现一个股票实时推送服务,并且展示如何在客户端通过 HTML 和 JavaScript 代码接收这些实时更新。Sanic 是一个异步的 Python 框架,非常适合构建高性能的 Web 应用程序和 API。我们将通过以下几个步骤来实现这个系统:
- 设置 Sanic WebSocket 服务端
- 创建 HTML 客户端代码
- 实现客户端与服务端的交互
1.1. 设置 Sanic WebSocket 服务端
首先,我们需要安装 Sanic 和相关的 WebSocket 库。可以使用以下命令来安装:
pip install sanic sanic_cors websockets
接下来,我们创建一个简单的 Sanic 应用程序,并使用 WebSocket 实现实时的股票数据推送。
import json
import uuid
from json import JSONDecodeErrorfrom sanic import Sanic, response
from sanic_cors import CORS, cross_origin
from sanic.websocket import WebSocketProtocol
from websockets import ConnectionClosedError, ConnectionClosedOK
import asyncio
import time
import randomapp = Sanic("StockWebSocket")
CORS(app)# 以股票代码为键的字典,存储订阅者列表
subscriptions = {}# 模拟股票行情数据,实际开发中用真实行情源代替
stock_data = {"a": {"stock_name": "阿里", "price": 150.00, "change": 0.25},"b": {"stock_name": "百度", "price": 2750.00, "change": 0.25},"t": {"stock_name": "腾讯", "price": 3400.00, "change": 0.25}
}class SubscriptObject(object):def __init__(self, register_id, ws):self.register_id = register_idself.ws = wsasync def recv(self):try:while True:msg = await self.ws.recv()if not msg:continuedata = json.loads(msg)action = data.get('action')stock_symbol = data.get('stock_symbol')if action == "subscribe":if stock_symbol in stock_data:if not subscriptions.get(stock_symbol):subscriptions[stock_symbol] = set()subscriptions[stock_symbol].add(self.ws)else:await self.ws.send(json.dumps({"error": "Unknown stock symbol"}))else:print(f"当前状态 {data}")except ConnectionClosedError:print(f'{self.register_id} 断开连接, 取消监听')except ConnectionClosedOK:print(f'{self.register_id} 断开连接, 取消监听')except JSONDecodeError:print(f'收到的数据解析失败')finally:# 清理客户端订阅for symbol in subscriptions:subscriptions[symbol].discard(self.ws)print("Client disconnected")async def stock_data_generator():while True:# 模拟股票数据更新stock_code_list = list(subscriptions.keys())for symbol in stock_code_list:ws_list = subscriptions.get(symbol, []).copy()dd = stock_data.get(symbol)data = dict()data['stock_name'] = dd['stock_name']data['price'] = dd['price'] + random.uniform(-5, 5)data['change'] = dd['change'] + random.uniform(-1, 1)data['timestamp'] = time.time()for ws in ws_list:try:await ws.send(json.dumps(data))except ConnectionClosedOK:print("连接取消前", subscriptions[symbol])subscriptions[symbol].discard(ws)print("连接取消后", subscriptions[symbol])await asyncio.sleep(1) # 每2秒更新一次@app.websocket("/ws/stock")
@cross_origin(app) # 为这个路由启用CORS
async def stock_websocket(request, ws):# 模拟实时更新股票价格register_id = uuid.uuid4().hexsub_obj = SubscriptObject(register_id, ws)await sub_obj.recv()# 启动股票数据更新任务
app.add_task(stock_data_generator())@app.route('/')
async def index(request):return await response.file('index.html')if __name__ == "__main__":app.run(host="0.0.0.0", port=8000, protocol=WebSocketProtocol)
1.2. 创建 HTML 客户端代码
我们需要一个简单的 HTML 页面,允许用户选择股票符号,并通过 WebSocket 连接到服务端以接收实时更新。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Stock Real-time Update</title><style>body {font-family: Arial, sans-serif;}.stock-data {margin: 20px;padding: 10px;border: 1px solid #ddd;}select {margin: 20px;padding: 5px;}</style>
</head>
<body>
<h1>实时股票行情</h1>
<select id="stock-select"><option value="a">阿里</option><option value="b">百度</option><option value="t">腾讯</option>
</select>
<div id="stock-container"><!-- 初始化一个空的 stock-data 元素,用于动态添加新的 stock-data 元素 --><div class="stock-data" id="stock-data-template" style="display: none;">股票名称: <span class="stock-name"></span><br>涨跌幅: <span class="change"></span><br>时间戳: <span class="timestamp"></span><br></div>
</div><script>const stockSelect = document.getElementById('stock-select');const stockContainer = document.getElementById('stock-container');const stockDataTemplate = document.getElementById('stock-data-template');function updateStock(symbol) {const ws = new WebSocket(`ws://localhost:8000/ws/stock`);const stockDataElement = stockDataTemplate.cloneNode(true); // 复制 stock-data 模板元素stockDataElement.id = `stock-data-${symbol}`; // 根据股票代码设置 IDstockDataElement.style.display = 'block'; // 显示元素stockContainer.appendChild(stockDataElement); // 将元素添加到容器中ws.onopen = function () {console.log("WebSocket connection established.");ws.send(JSON.stringify({action: 'subscribe',stock_symbol: symbol}));};ws.onmessage = function (event) {const data = JSON.parse(event.data);const stockData = stockDataElement.getElementsByClassName('stock-data')[0];if (data.error) {stockData.innerHTML = `<p>${data.error}</p>`;} else {console.log("ddddddd", data)stockDataElement.getElementsByClassName('stock-name')[0].textContent = data.stock_name;stockDataElement.getElementsByClassName('change')[0].textContent = data.change;stockDataElement.getElementsByClassName('timestamp')[0].textContent = data.timestamp;}};ws.onerror = function (error) {console.log("WebSocket Error: ", error);};}stockSelect.addEventListener('change', function () {const selectedSymbol = stockSelect.value;updateStock(selectedSymbol);});// 初始化加载第一个股票的数据updateStock(stockSelect.value);
</script>
</body>
</html>
访问地址:http://localhost:8000
2. 实现客户端与服务端的交互
在上面的代码中,客户端通过 WebSocket 连接到服务端,并根据输入的股票符号接收实时更新。服务端定期推送模拟的股票数据到所有订阅该股票符号的客户端。
3. 总结
通过以上步骤,我们实现了一个基于 Sanic 的 WebSocket 股票实时推送服务,并创建了一个简单的 HTML 客户端以接收这些实时更新。这个示例可以根据实际需求进行扩展和优化,如连接管理、数据来源的整合、错误处理等。希望这个示例能帮助你在实际项目中实现实时数据推送功能。
🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
💖The End💖点点关注,收藏不迷路💖 |
相关文章:

sanic + webSocket:股票实时行情推送服务实现
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storm…...

Unity动态给按钮各个状态下的图片赋值
Unity动态给按钮各个状态下的图片赋值 using UnityEngine; using UnityEngine.UI; public class ButtonOnClickTest : MonoBehaviour {public Button btn;public Sprite _highlighterSprite;public Sprite _pressedSprite;public Sprite _selectesdSprite;public Sprite _disa…...

xiaomi pad 6PRO 小米平板6 pro hyperOS降级 澎湃os 降级MIUI 14 教程 免解锁BL 降级,168小时解锁绑定
小米平板 6 Pro 机型代号 :liuqin 降级MIUI 14 小米澎湃 OS 正式版 澎湃OS安卓发布日期卡刷包线刷包OS1.0.7.0.UMYCNXM14.02024-07-13miui_LIUQIN_OS1.0.7.0.UMYCNXM_d618a5c980_14.0.zipliuqin_images_OS1.0.7.0.UMYCNXM_20240705.0000.00_14.0_cn_8cbf5920be.…...

MySQL 备份一个表
语法(创建一个与table1结构相同的新表table2,并且将table1的数据复制到table2): create table table2 as select * from table1 举例(备份tb_log表到tb_log_20240815中去): create table tb_log_20240815 as select * from tb_log...

鸿蒙开发入门day10-组件导航
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ) 目录 组件导航 (Navigation) 设置页面显示模式 设置标题栏模式 设置菜…...

虚拟机Linux的坑 | VMware无法从主机向虚拟机 跨系统复制粘贴拖动 文件/文本
这个情况下,还是没办法跨系统拖拽文件 解决办法: 在终端中输入命令 sudo apt-get autoremove open-vm-tools sudo apt-get install open-vm-tools sudo apt-get install open-vm-tools-desktop过程中只要需要选择是否覆盖的地方,都输入&…...
Chat App 项目之解析(二)
Chat App 项目介绍与解析(一)-CSDN博客文章浏览阅读76次。Chat App 是一个实时聊天应用程序,旨在为用户提供一个简单、直观的聊天平台。该应用程序不仅支持普通用户的注册和登录,还提供了管理员登录功能,以便管理员可以…...

数据结构与算法 - 双指针
一、移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12]输出: [1,3,12,0,0]示例 2: 输入: nums …...

Python3网络爬虫开发实战(10)模拟登录(需补充账号池的构建)
文章目录 一、基于 Cookie 的模拟登录二、基于 JWT 模拟登入三、账号池四、基于 Cookie 模拟登录爬取实战五、基于JWT 的模拟登录爬取实战六、构建账号池 很多情况下,网站的一些数据需要登录才能查看,如果需要爬取这部分的数据,就需要实现模拟…...

SQL 调优最佳实践笔记
定义与重要性 SQL 调优:提高SQL性能,减少查询时间和资源消耗。目标:减少查询时间和扫描的数据行数。 基本原则 减少扫描行数:只扫描所需数据。使用合适索引:确保WHERE条件命中最优索引。合适的Join类型:…...

Eclipse的使用配置教程:必要设置、创建工程及可能遇到的问题(很详细,很全面,能解决90%的问题)
Eclipse的使用配置: Ⅰ、Eclipse 的必要配置:1、Eclipse 的安装:其一、将 Eclipse 解压或安装到没有中文且没有空格的路径下。其二、拿到 eclipse.exe 文件,傻瓜式安装即可; 2、设置工作空间(workspace):其一、首次启动…...

遗传算法与深度学习实战(4)——遗传算法详解与实现
遗传算法与深度学习实战(4)——遗传算法详解与实现 0. 前言1. 遗传算法简介1.1 遗传学和减数分裂1.2 类比达尔文进化论 2. 遗传算法的基本流程2.1 创建初始种群2.2 计算适应度2.3 选择、交叉和变异2.4算法终止条件 3. 使用 Python 实现遗传算法3.1 构建种…...

Nginx+Tomcat实现负载均衡、动静分离集群部署
文章目录 一、Nginx实现负载均衡原理1.正向代理和反向代理2.负载均衡模式1. 轮询(Round Robin):2. 最少连接数(Least Connections):3. IP 哈希(IP Hash):4. 加权轮询…...

英语学习8月19日
词根前缀后缀 accomplishment 成就 acid n.酸的,adj.酸的 acidity n.酸性 ace adj.顶尖的 acute adj.敏锐的;急性的;严重的 acuity n.敏锐 obtuse adj.迟钝的;钝角的 acuity n.敏锐,严重 1.前缀ac: 尖&#x…...

关于windows环境使用nginx的一些性能问题
遇到的问题 最近在一个windows环境中部署nginx,遇到了以下问题: 1. nginx启动了九个线程(1master8woekr),但是所有链接都被1个woker接收,其余worker不工作 2. 用户端访问web很慢,登录服务器使…...

“解决Windows电脑无法投影到其他屏幕的问题:尝试更新驱动程序或更换视频卡“
背景: 今天在日常的工作中, 我想将笔记本分屏到另一个显示屏,我这电脑Windows10,当我按下Windows键P键,提示我"你的电脑不能投影到其他屏幕,请尝试从新安装驱动程序或使用"遇到这种问题。 解决方法1: 1.快…...

第10章 无持久存储的文件系统 (2)
目录 10.1 proc文件系统 10.1.2 数据结构 10.1.3 初始化 10.1.4 装载 proc 文件系统 10.1.5 管理 /proc 数据项 10.1.6 读取和写入信息 10.1.7 进程相关信息 10.1.8 系统控制机制 本专栏文章将有70篇左右,欢迎关注,查看后续文章。 10.1 proc文件…...

云计算实训29——mysql主从复制同步、mysql5.7版本安装配置、python操作mysql数据库、mycat读写分离实现
一、mysql主从复制及同步 1、mysql主从自动开机同步 2、配置mysql5.7版本 mysql-5.7.44-linux-glibc2.12-x86_64.tar 启动服务、登录 对数据库进行基本操作 3、使用python操纵mysql数据库 4、编辑python脚本自动化操纵mysql数据库 二、mycat读写分离实现 1.上传jdk和mycat安装…...

AI搜索引擎Perplexica的本地部署(之二)Perplexica的非docker安装
Perplex 是一个开源的AI 驱动的搜索引擎,可以使用 Grok 和 Open AI 等模型在计算机上本地安装和运行。它为学术研究、写作、YouTube 和 Reddit 提供了一系列搜索功能。用户可以通过选择不同的模型、设置本地嵌入模型和探索各种搜索选项来定制他们的体验。该工具演示…...

Oracle环境下在相同参数和数据源的情况,mybatis-plus查询和sql查询结果不一致
场景: 在系统中某个对象执行修改的时候,查询对象为空,造成修改报错 分析: 在传参中有一个eq的参数需要传null,mybatis-plus在执行eq时可能是拼成" null",但是oracle中查null必须要用is null, null是查不出东西的 解决: 改成用sql查询修改,或者加判断如果这个参…...

springboot静态资源访问问题归纳
以下内容基于springboot 2.3.4.RELEASE 1、默认配置的springboot项目,有四个静态资源文件夹,它们是有优先级的,如下: "classpath:/META-INF/resources/", (优先级最高) "classpath:/reso…...

HTML与CSS学习Day01
文章目录 一 、CSS技巧1.1 CSS精灵(CSS Sprites)1.1.1 实现步骤1.1.2 例子 1.2 字体图标1.2.1如何使用字体图标1.2.2 字体图标使用总结 1.3 垂直对齐方式vertical-align1.3.1 值1.3.2 例子 1.4 过渡效果transition1.4.1 CSS过渡效果(transiti…...

Tina-Linux Bootloaer简述
Tina-Linux Bootloaer简述 目录介绍 ubuntuubuntu1804:~/tina-v2.0-sdk/lichee/brandy-2.0$ tree -L 1 . ├── build.sh ├── opensbi ├── spl //boot0 ├── spl-pub //boot0 ├── tools └── u-boot-2018 /ubootTina-Linux 启动流程简述...

【Python】 Scrapyd:Python Web Scraping 的强大分布式调度工具
我听见有人猜 你是敌人潜伏的内线 和你相知多年 我确信对你的了解 你舍命救我画面 一一在眼前浮现 司空见惯了鲜血 你忘记你本是娇娆的红颜 感觉你我彼此都那么依恋 🎵 许嵩《内线》 在网络爬虫项目中,Scrapy 是 Python 中最流行和…...

吴恩达机器学习课后题-01线性回归
线性回归 一.单变量线性回归题目损失函数(代价函数)梯度下降函数代价函数可视化整体代码 二.多变量线性回归特征归一化(特征缩放)不同学习率比较 正规方程正规方程与梯度下降比较 使用列表创建一维数组使用嵌套列表创建二维数组&a…...

白盒报告-jacoco
使用jacoco--执行nvn test 运行过程: 1、idea执行mvn test ,运行过程如下: a.maven-surefire-plugin:0.8.7执行目标动作:prepare-agent, 目的是:执行目标动作是为了在当前的项目名下生成jecoco.…...

【MySQL】SQL语句执行流程
目录 一、连接器 二、 查缓存 三、分析器 四、优化器 五、执行器 一、连接器 学习 MySQL 的过程中,除了安装,我们要做的第一步就是连接上 MySQL 在一开始我们都是先使用命令行连接 MySQL mysql -h localhost -u root -p 你的密码 使用这个命令…...

Selenium自动化防爬技巧:从入门到精通,保障爬虫稳定运行,通过多种方式和add_argument参数设置来达到破解防爬的目的
在Web自动化测试和爬虫开发中,Selenium作为一种强大的自动化工具,被广泛用于模拟用户行为、数据抓取等场景。然而,随着网站反爬虫技术的日益增强,直接使用Selenium很容易被目标网站识别并阻止。因此,掌握Selenium的防爬…...

从数据类型到变量、作用域、执行上下文
从数据类型到变量、作用域、执行上下文 JS数据类型 分类 1》基本类型:字符串String、数字Number、布尔值Boolean、undefined、null、symbol、bigint 2》引用类型:Object (Object、Array、Function、Date、RegExp、Error、Arguments) Symbol是ES6新出…...

一文读懂:AI时代到底需要什么样的网络?
各位小伙伴们大家好哈,我是老猫。 今天跟大家来聊聊数据中心网络。 提到网络,通常把网络比作高速公路,网卡相当于上下高速公路的闸口,数据包就相当于运送数据的汽车,交通法规就是“传输协议”。 如高速公路也会堵车一…...