第五节:使用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几个系统的消息对接和众多业务场景设计,稳定、准确运行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

命名空间多线程计时(C++基础)

命名空间 不要在头文件内使用using namespace&#xff0c;一定要确保实在一个足够小的作用域下使用&#xff0c;在哪个范围内&#xff0c;比如函数、if语句等&#xff0c;但一定不要在头文件中使用&#xff01;&#xff01;&#xff01; 上述示例中&#xff0c;会调用orange中…

windows系统图标变白设置

我们在使用系统的时候&#xff0c;通常会在桌面创建图标&#xff0c;有时候桌面图标过多&#xff0c;整理图标放在新建文件夹的时候&#xff0c;图标变白&#xff0c;通常情况下都是缓存问题&#xff0c;这里也是删除缓存解决演示系统&#xff1a;windows11 1显示图标缓存目录 …

用Python进行机器学习:Scikit-learn的入门与实践【第126篇—Scikit-learn的入门】

用Python进行机器学习&#xff1a;Scikit-learn的入门与实践 随着机器学习在各个领域的广泛应用&#xff0c;Python成为了一个备受欢迎的机器学习工具之一。在众多机器学习库中&#xff0c;Scikit-learn因其简单易用、功能强大而备受青睐。本文将介绍Scikit-learn的基本概念&am…

数据持久化(Json)

平常写代码的时候就应该习惯性的加【SerializeField】System.Serializable 如果是公有变量可以不加 泛型就要用<> JSon语法 之后Lua热更新的学习也会使用Sublime Text Excel转Json https://www.bejson.com/json/col2json 记得检查一下&#xff0c;得到的Json格式是否…

SpringBoot3快速入门

目录 一、快速创建项目 二、手动创建一个工程 一、快速创建项目 1、使用官网提供的spring组件创建一个springboot3工程&#xff0c;springboot3要使用JDK17以上的版本 选择配置点击finish&#xff0c;刷新maven 创建一个controller层&#xff0c;写一个demo&#xff0c;点击运…

Edu 12 --- Simple Subset -- 题解 (一个比较巧妙的思维算法题)

Simple Subset&#xff1a; 题解&#xff1a; 思路解析&#xff1a; 题目要求任意两个数的和为质数&#xff0c;那我们最坏情况就是任意选择一个数&#xff0c;此时子集为最大。 如果子集中有两个奇数或者偶数&#xff0c;他们两个之和一定会被2整除&#xff0c;那么我们只能…

JVM垃圾收集器-serial.parNew,parallelScavnge,serialOld,parallelOld,CMS,G1

垃圾收集器 分代模型 适用于新生代&#xff1a; serial parNew parallel Scaavenge 适用于老年代&#xff1a; CMS serial Old(msc) paraller Old 分区模型 适用于超大容量&#xff1a; G1 分代模型 serial /serial Old收集器 1.单线程收集器 2.收集时会暂停其他线程&…

从零搭建Vue项目

目录 环境准备 NodeJS安装 ​编辑 2. 选择安装目录 3. 验证NodeJS环境变量 4. 配置npm的全局安装路径 5. 切换npm的淘宝镜像 6. 安装Vue-cli Vue项目创建 1. 打开UI界面 2. 打开项目管理器 3. 创建项目 vue项目目录结构介绍 运行vue项目 Vue项目开发流程 Vue组…

k8s CKA upgrade - Kubeadm 版本升级实测

升级版本最好是逐步去升级&#xff0c;不要跨越多个大版本&#xff0c;可能会出错 大体流程&#xff1a; 1.先确定升级版本 2.升级kubeadm 3.驱逐节点 4.升级kubelet和kubectl 5.重启kubelet服务 6.恢复节点&#xff0c;使其上线 1.查看现版本&#xff1a;升级版本 kubectl ge…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的夜间车辆检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发夜间车辆检测系统对于自动驾驶技术具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个夜间车辆检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不同模型间…

oracle临时表空间不释放

项目报错 nested exception is java.sql.SQLException: ORA-01652: unable to extend temp segment by 128 in tablespace TEMP 原因是临时表空间满了&#xff0c;临时表空间一直增长&#xff0c;未释放导致临时表空间使用率100%。 查询临时表空间使用率 --临时表空间利用率…

【MySQL 系列】MySQL 语句篇_DDL 语句

DDL&#xff08; Data Definition Language&#xff0c;数据定义语言&#xff09;用在定义或改变表的结构数据类型、表之间的链接和约束等初始化工作上。常用的语句关键字包括 CREATE、 DROP、 ALTER 等。 文章目录 1、MySQL 中的 DQL 语句2、MySQL 中库表的 DQL 语句详解2.1、…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的常见手势识别系统(深度学习模型+UI界面代码+训练数据集)

摘要&#xff1a;开发手势识别系统对于增强人机交互和智能家居控制领域的体验非常关键。本博客详尽阐述了通过深度学习技术构建手势识别系统的过程&#xff0c;并附上了全套实施代码。系统采用了先进的YOLOv8算法&#xff0c;并通过与YOLOv7、YOLOv6、YOLOv5的性能对比&#xf…

代码学习记录17

随想录日记part17 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.12 主要内容&#xff1a;今天的主要内容是二叉树的第六部分&#xff0c;主要涉及二叉搜索树的最小绝对差 &#xff1b;二叉搜索树中的众数&#xff1b;二叉树的最近公共祖先。 530.二叉搜索树…

关于c++的protected关键字

关于c的protected关键字 分类引言例子1&#xff09;错误的demo2&#xff09;改正的demo protected在c中的含义与作用 分类 c基础知识 引言 做了很业务&#xff0c;c基础知识却忘了很多&#xff0c;今天看了一个例子&#xff0c;唤醒了我关于c三大特性之一----封装&#xff0…

VulnHub - Lampiao

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog Lampiao 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/lampiao-1,249/ 0x01 信息收集 Nm…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的远距离停车位检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发远距离停车位检测系统对于提高停车效率具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个远距离停车位检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记08_行为歧视

1. 常见的报价方式 1.1. 水滴定价&#xff08;Drip Pricing&#xff09; 1.1.1. 用一个较低的初始价格吸引消费者入局&#xff0c;之后再不断收取附加费用 1.2. 打折促销 1.2.1. 在一个远被高估的原价上制造折扣价格的魅力 1.2…

免费搭建导航网站教程带免费空间域名源码

使用免费空间和免费域名免费搭建一个导航网站 手把手视频教程 https://pan.xunlei.com/s/VNsoMehs7RCjz3IClV6h2vNMA1?pwdq596#

Docker安装步骤笔记

一、环境准备 VM网络配置 打开VMware软件 --编辑 --虚拟网络编辑器 二、VM创建虚拟机 三、安装rhel8.9操作系统 1、rhel8.9 镜像下载 第一步&#xff1a;进入redhat官网进行注册第二步&#xff1a;下载rhel8.9镜像文件 https://access.redhat.com/downloads/content/rhel …