当前位置: 首页 > news >正文

第五节:使用SMB开发WebSocket通信

一、概述

本节主要讲解在SMB中如何进行websocket快速开发,实现客户端连接、关闭、消息通讯等功能。

示例下载:https://download.csdn.net/download/lllllllllluoyi/88949743

二、创建WebSocket服务器

1、在csdnProject工程中新建一个消息流。

添加WebSocket Server和四个Java计算节点组件,具体流程如图:

2、各组件说明

WebSocket1:websocket服务器组件,端口设置8100;

route:主要作用是路由。因为WebSocket1会产生open、close、onMessage动作,需要在这里进行逻辑分流,具体代码是:

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;public class csdn_websocketServer_route {private String routeLabels = "";public String execute(MessageModel messageModel,String message){String eventName = messageModel.eventName;switch(eventName){case "open":routeLabels = "openWebSocket";break;case "close":routeLabels = "closeWebSocket";break;default:routeLabels = "processWebSocket";break;}return message;}public String getRouteLabels(){return routeLabels;}}

openWebSocket:客户端连接服务器的处理逻辑。

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
import sashulin.websocket.SashulinWebSocket;
public class csdn_websocketServer_openWebSocket {private String routeLabels = "";public String execute(MessageModel messageModel,String message){System.out.println("已连接webSocket服务器,参数信息:"+message);//在内存中保存IP对应的websocket对象SashulinWebSocket webSocket = (SashulinWebSocket)messageModel.object;JSONObject msgJson = new JSONObject(message);String ip = msgJson.getString("clientIP");if (!webSocket.clients.containsKey(ip)){webSocket.clients.put(ip, messageModel.object2);}return "ok";}public String getRouteLabels(){return routeLabels;}
}

closeWebSocket:客户端关闭的逻辑处理。

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
import sashulin.websocket.SashulinWebSocket;
public class csdn_websocketServer_closeWebSocket {private String routeLabels = "";public String execute(MessageModel messageModel,String message){System.out.println("已断开与webSocket服务器的连接,参数信息:"+message);SashulinWebSocket webSocket = (SashulinWebSocket)messageModel.object;String ip = message;if (webSocket.clients.containsKey(ip)){webSocket.clients.remove(ip);}return "ok";}public String getRouteLabels(){return routeLabels;}}

processWebSocket:消息收到后的处理逻辑。

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
public class csdn_websocketServer_processWebSocket {private String routeLabels = "";public String execute(MessageModel messageModel,String message){System.out.println("收到消息:"+message);return "ok";}public String getRouteLabels(){return routeLabels;}}

三、JavaScript向websocket发送消息

通过JavaScript中向websocket服务器连接,发送消息、关闭动作。本例示使用HtmlVCL前端框架进行开发,也可以自己写测试界面代码。界面效果如图:

本示例中包含了两个文件:index.html和websocket.html。

index.html代码
 

<meta charset="utf-8"> <link rel="stylesheet" href="css/vcl.css"><script type="text/javascript" src="js/vcl.js"></script><script type="text/javascript">function main() {var form = new HtmlForm(null);form.align = "center";form.color = "blue";form.Refresh();var popupMenu1 = new HtmlPopupMenu(form);popupMenu1.items = [{id:1,text:"copy"},{id:2,text:"paste"},{id:-1,text:"-"},{id:3,text:"cut"}];popupMenu1.onclick = function(obj,evt){alert(obj.text);alert(evt.id);alert(evt.text);}var topPanel = new HtmlPanel(form);topPanel.align = "top";topPanel.alignment = "center";topPanel.color = "#333";topPanel.fontSize = 14;topPanel.fontColor = "White";topPanel.name="topPanel1";//topPanel.text = "<h1>ChromeWebBrowser.net User Guide</h1>";topPanel.Refresh();var logoPanel = new HtmlPanel(topPanel);logoPanel.align = "left";logoPanel.width = 200;logoPanel.Refresh();var logoImg = new HtmlImage(logoPanel);logoImg.imageUrl = "img/sashulin.png";logoImg.left = 18;logoImg.top = 15;logoImg.width = 32;logoImg.height = 32;logoImg.Refresh();var top_right_panel = new HtmlPanel(topPanel);top_right_panel.align = "right";top_right_panel.width = 200;top_right_panel.Refresh();var userImg = new HtmlImage(top_right_panel);userImg.imageUrl = "img/p.png";userImg.left = 10;userImg.top = 20;userImg.width = 20;userImg.height = 20;userImg.Refresh();var userLabel = new HtmlLabel(top_right_panel);userLabel.alignment = "left";userLabel.left = 40;userLabel.top = 23;userLabel.width = "auto";userLabel.height = 25;userLabel.text = "Hi,Roy";userLabel.fontColor = "white";userLabel.fontSize = 14;userLabel.Refresh();var quitButton = new HtmlLinkButton(top_right_panel);quitButton.top = 20;quitButton.left = 120;quitButton.width = "auto";quitButton.height = 25;quitButton.text = "退出";quitButton.fontColor = "white";quitButton.fontSize = 14;quitButton.setUrl("index.html");quitButton.Refresh();var top_center_panel = new HtmlPanel(topPanel);top_center_panel.align = "center";top_center_panel.Refresh();var popupMenu2 = new HtmlPopupMenu(form);popupMenu2.items = [{id:1,text:"白血病"},{id:2,text:"肺炎"},{id:-1,text:"-"},{id:3,text:"流感"}];popupMenu2.onclick = function(obj,evt){alert(obj.text);alert(evt.id);alert(evt.text);}var titleLabel = new HtmlLabel(logoPanel);titleLabel.alignment = "left";titleLabel.left = 60;titleLabel.top = 20;titleLabel.width = 300;titleLabel.height = 25;titleLabel.text = "Sashulin Message Broker示例";titleLabel.fontColor = "#00ffe2";titleLabel.fontSize = 16;titleLabel.Refresh();var leftPanel = new HtmlPanel(form);leftPanel.name = "leftPanel1";leftPanel.align = "left";leftPanel.color = "#e6e6e6";leftPanel.width = "200";leftPanel.Refresh();var frame = new HtmlFrame(form);frame.align = "center";frame.color = "White";// frame.setUrl("pages/method-EN.html");frame.setUrl("pages/tabs.html");frame.Refresh();var bottomPanel = new HtmlPanel(form);bottomPanel.align = "bottom";bottomPanel.alignment = "center";bottomPanel.color = "#000";bottomPanel.height = 25;bottomPanel.fontColor = "White";bottomPanel.text = "@Author: Roy (173783000@qq.com)";bottomPanel.Refresh();var navBar = new HtmlNavBar(leftPanel);navBar.name = "navBar1";navBar.align = "center";navBar.width = "200";navBar.alignment = "center";navBar.color = "#393D49";navBar.items = [{"title":"WebSocket","items":[{"id":"1","caption":"WebSocket","img":"img/p.png"}]}];navBar.onGroupItemClick = function(event){//alert(event.control.id+":"+event.control.text); var url = "";switch(event.control.id){case "1":url = "pages/websocket.html";break;default:url = "pages/method-EN.html";break;}frame.setUrl(url);}navBar.Refresh();}</script>

websocket.html代码

<!DOCTYPE html>
<script type="text/javascript" src="../js/vcl.js"></script>
<script type="text/javascript">function main() {var websocket;var form = new HtmlForm(null);form.align = "center";form.color = "#eee";form.Refresh();//第一排var button1 = new HtmlButton(form);button1.left = 380;button1.top = 50;button1.width = 100;button1.height = 30;button1.text = "连接"button1.onclick = function () {websocket = new WebSocket(edit1.text);websocket.onerror = (event)=>{  label_status.setText("WebSocket连接发生错误");};//连接成功建立的回调方法  websocket.onopen = (event) => {  label_status.setText("已连接");}  //接收到消息的回调方法  websocket.onmessage = (event) => {  edit_content.setText(event.data);}  //连接关闭的回调方法  websocket.onclose = (event) => {  label_status.setText("已关闭");}}button1.Refresh();var closeButton = new HtmlButton(form);closeButton.left = 500;closeButton.top = 50;closeButton.width = 100;closeButton.height = 30;closeButton.text = "关闭"closeButton.onclick = function () {	websocket.close();}closeButton.Refresh();var label_status = new HtmlLabel(form);label_status.text = "--";label_status.left = 100;label_status.top = 20;label_status.Refresh();var label1 = new HtmlLabel(form);label1.text = "服务器";label1.left = 100;label1.top = 50;label1.Refresh();var edit1 = new HtmlEdit(form);edit1.text = "ws://127.0.0.1:8100";edit1.left = 160;edit1.top = 50;edit1.width = 200;edit1.Refresh();//第二排var button2 = new HtmlButton(form);button2.left = 380;button2.top = 100;button2.width = 100;button2.height = 30;button2.text = "发送"button2.onclick = function () {}button2.Refresh();var label2 = new HtmlLabel(form);label2.text = "发送内容";label2.left = 100;label2.top = 100;label2.Refresh();var edit2 = new HtmlEdit(form);edit2.text = "测试消息";edit2.left = 160;edit2.top = 100;edit2.width = 200;edit2.Refresh();var label3 = new HtmlLabel(form);label3.text = "收到内容";label3.left = 100;label3.top = 150;label3.Refresh();var edit_content = new HtmlEdit(form);edit_content.text = "";edit_content.left = 160;edit_content.top = 150;edit_content.width = 200;edit_content.Refresh();}</script>

运行的效果:

四、两个客户端通讯

在真实场景中是进行消息推送。我们在csdnProject工程进行以下先改:

1、增加一个api接口

这个消息流的逻辑是:开放一个api接口,用户调用接口后向服务器发送websocket消息。在action组件中进行对websocketClient组件的操控,代码如:

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
public class csdn_HttpFlow_action {private String routeLabels = "";public String execute(MessageModel messageModel,String message){JSONObject json = new JSONObject(message);String action = json.getString("action");String text = json.getString("text");switch(action){case "send":FlowApi.execute(this,"WebSocketClient1","send",message);break;case "close":FlowApi.execute(this,"WebSocketClient1","close",text);break;}return "ok";}public String getRouteLabels(){return routeLabels;}}

FlowApi.execute(this,"WebSocketClient1","send",message); //执行websocketClient的Send操作。

FlowApi.execute(this,"WebSocketClient1","close",text); //执行websocketClient的Close操作。

2、修改processWebSocket组件代码

修改服务器的消息接收后的逻辑处理。即向指定的客户发送消息:

package sashulin.apps;
import sashulin.Models.MessageModel;
import sashulin.applications.FlowApi;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
import sashulin.websocket.SashulinWebSocket;
import org.java_websocket.WebSocket;
public class csdn_websocketServer_processWebSocket {private String routeLabels = "";public String execute(MessageModel messageModel,String message){System.out.println("收到消息:"+message);JSONObject json = new JSONObject(message);String destIP = json.getString("destIP");String text = json.getString("text");SashulinWebSocket webSocket = (SashulinWebSocket)messageModel.object;if (webSocket.clients.containsKey(destIP)){Object obj = webSocket.clients.get(destIP);WebSocket conn = (WebSocket)obj;conn.send(text);}return "ok";}public String getRouteLabels(){return routeLabels;}}

3、测试消息发送

首先在SashulinMessageBroker示例中连接服务器;

然后再PostMan中发送消息:

SMB示例中收到来自于postman的消息:

结束语:应用于生产环境中会更复杂,但核心点还是在ProcessMessage组件这里,把消息推送何处?推送几次?这些可以做成策略。目前我们全院消息通讯平台也是按这个逻辑进行开发,在国内西南某大型儿童医院为例,进行了2000个客户端,20几个系统的消息对接和众多业务场景设计,稳定、准确运行。

相关文章:

第五节:使用SMB开发WebSocket通信

一、概述 本节主要讲解在SMB中如何进行websocket快速开发&#xff0c;实现客户端连接、关闭、消息通讯等功能。 示例下载&#xff1a;https://download.csdn.net/download/lllllllllluoyi/88949743 二、创建WebSocket服务器 1、在csdnProject工程中新建一个消息流。 添加W…...

Nginx和Ribbon实现负载均衡的区别

Nginx和Ribbon的区别 1. Nginx服务器端负载均衡&#xff1a; 1、Nginx是客户端所有请求统一交给nginx&#xff0c;由nginx进行实现负载均衡请求转发&#xff0c;属于服务器端负载均衡。即请求有nginx服务器端进行转发。 3、Nginx是服务端的负载均衡&#xff0c;Ribbon是客户端…...

流畅的Python(十九)-动态属性和特性

一、核心要义 在Python中,数据的属性和处理数据的方法,统称属性。方法&#xff0c;只是可调用的属性。除了这两者之外,我们还可以创建特性(property),在不改变类接口的前提下,使用存取方法(即读值方法和设值方法)修改数据属性。 二、代码示例 0、相关知识点 #!/usr/bin/env…...

确保云原生部署中的网络安全

数字环境正在以惊人的速度发展&#xff0c;组织正在迅速采用云原生部署和现代化使用微服务和容器构建的应用程序&#xff08;通常运行在 Kubernetes 等平台上&#xff09;&#xff0c;以推动增长。 无论我们谈论可扩展性、效率还是灵活性&#xff0c;对于努力提供无与伦比的用…...

【分布式websocket 】前端vuex管理客户端消息crud!使用localStorage来存储【第19期】

前言 聊天系统客户端是要存储消息的&#xff0c;因为所有所有的历史消息都从服务器拉的话一方面服务器压力大&#xff0c;另一方面也耗费用户流量。所以客户端存储消息是势在必行的。如何存储呢上一篇文章也写了&#xff0c;大概就是浏览器的话是localStorage或者IndexedDB。然…...

venv uvicorn python 虚拟服务器外网无法访问

python -m venv .venv source ./.venv/bin/activate pip install -r requirements.txt ./run.sh source ./.venv/bin/activate uvicorn main:app --reload 虚拟web服务器外网访问控制台启动命令用以下代码启动 uvicorn main:app --host 0.0.0.0 --port 8501 --reload 启动到后…...

一款博客网站源码

一款博客网站源码 源码软件库 为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff…...

Mr-Robot1靶场练习靶场推荐小白入门练习靶场渗透靶场bp爆破wordpress

下载链接&#xff1a; Mr-Robot: 1 ~ VulnHub 安装&#xff1a; 打开vxbox&#xff0c;菜单栏----管理----导入虚拟电脑 选择下载完的ova文件&#xff0c;并修改想要保存的位置&#xff08;也可以保持默认位置&#xff09; 导入完成后可以根据自己的情况去配置网络链接方式 完成…...

数据仓库的设计开发应用(三)

目录 五、数据仓库的实施&#xff08;一&#xff09;数据仓库的创建&#xff08;二&#xff09;数据抽取转换加载 六、数据仓库系统的开发&#xff08;一&#xff09;开发任务&#xff08;二&#xff09;开发方法&#xff08;三&#xff09;系统测试 七、数据仓库系统的应用&am…...

【04】WebAPI

WebAPI 和标准库不同,WebAPI 是浏览器提供的一套 API,用于操作浏览器窗口和界面 WebAPI 中包含两个部分: BOM:Browser Object Model,浏览器模型,提供和浏览器相关的操作DOM:Document Object Model,文档模型,提供和页面相关的操作BOM BOM 提供了一系列的对象和函数,…...

数据预处理在数据挖掘中的重要性

数据挖掘作为从大量数据中提取有用信息和知识的过程&#xff0c;其结果的准确性和可靠性直接受到数据质量的影响。因此&#xff0c;数据预处理在数据挖掘中扮演着至关重要的角色。让我们探讨数据质量对数据挖掘结果的影响&#xff0c;并介绍常见的数据预处理方法以及它们如何提…...

Java并发编程—JUC线程池架构

Java并发编程&#xff08;JUC&#xff0c;Java Utilities Concurrency&#xff09;中的线程池架构是Java提供的一种用于管理和复用线程的机制。线程池的主要目标是减少线程创建和销毁的开销&#xff0c;提高系统的响应速度&#xff0c;并通过合理的线程管理和资源分配&#xff…...

Android input输入子系统

一.Android input输入子系统简介 Input系统是Android系统中负责处理用户输入操作的核心组件&#xff0c;它负责从各种输入设备&#xff08;如屏幕、键盘、鼠标等&#xff09;获取原始的输入事件&#xff08;如按键、触摸、滑动等&#xff09;&#xff0c;并将其转换为Android应…...

如何在webapp中于动发布一个应用

目录 第一步&#xff1a;在webapp文件夹内自定义文件夹第二步&#xff1a;生成一个文本&#xff0c;并把后缀改为 .html第三步&#xff1a;进入bin文件夹打开服务第四步&#xff1a;打开方式选择java第六步&#xff1a;输入你想输出的东西第七步&#xff1a;双击运行即可 第一步…...

部署一个本地的ChatGPT(Ollama)

一 下载Ollama Ollama下载地址&#xff1a;https://ollama.com/download 下载完后 二 安装运行 双击下载好的OllamaSetup.exe开发 安装Ollama: 安装完成后&#xff0c;多了一个Ollama的菜单如下图 &#xff1a; Ollama安装好默认是配置开机运行&#xff0c;如果没有运行可以在…...

Vue 3中的reactive:响应式状态的全面管理

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

【网络】详解HTTPS及探究加密过程

目录 一、什么是HTTPS1、加密解密是什么2、为什么要加密3、常见的加密方式1、对称加密2、非对称加密 二、探究HTTPS如何实现加密1、方案一----只使用对称加密2、方案二----只使用非对称加密3、方案三----双方都使用非对称加密4、方案四----非对称加密 对称加密5、中间人攻击6、…...

【C语言】字符与字符串---从入门到入土级详解

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.字符类型和字符数组&#xff08;串&#xff09;简介 1.ASCII 2.定义&#xff0c;初始化&#xff0c;使用 1>字符的定义及初始化 2>字符串的定义及初始化 二.…...

Github Copilot 工具,无需账号,一键激活

① 无需账号&#xff0c;100%认证成功&#xff01;0风险&#xff0c;可联网可更新&#xff0c;&#xff0c;支持copilot版本升级&#xff0c;支持chat ② 支持windows、mac、linux系统等设备 ③一号通用&#xff0c;支持所有IDE(AppCode,CLion,DataGrip,GoLand,IntelliJ IDEA …...

node: -max-old-space-size=xxx is not allowed in NODE_OPTIONS

问题描述 在启动node项目时&#xff0c;出现了OOM参照网上的处理方案&#xff0c;设置了环境变量&#xff1a; export NODE_OPTIONS"–max-old-space-size8192"当再次通过npm run docs:dev运行node项目的时候出现了如下错误&#xff1a; node: -max-old-space-siz…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...