愛做網(wǎng)站外國2023智慧樹網(wǎng)絡(luò)營銷答案
一、概述
本節(jié)主要講解在SMB中如何進(jìn)行websocket快速開發(fā),實(shí)現(xiàn)客戶端連接、關(guān)閉、消息通訊等功能。
示例下載:https://download.csdn.net/download/lllllllllluoyi/88949743
二、創(chuàng)建WebSocket服務(wù)器
1、在csdnProject工程中新建一個消息流。
添加WebSocket Server和四個Java計(jì)算節(jié)點(diǎn)組件,具體流程如圖:
2、各組件說明
WebSocket1:websocket服務(wù)器組件,端口設(shè)置8100;
route:主要作用是路由。因?yàn)閃ebSocket1會產(chǎn)生open、close、onMessage動作,需要在這里進(jìn)行邏輯分流,具體代碼是:
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:客戶端連接服務(wù)器的處理邏輯。
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服務(wù)器,參數(shù)信息:"+message);//在內(nèi)存中保存IP對應(yīng)的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:客戶端關(guān)閉的邏輯處理。
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服務(wù)器的連接,參數(shù)信息:"+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發(fā)送消息
通過JavaScript中向websocket服務(wù)器連接,發(fā)送消息、關(guān)閉動作。本例示使用HtmlVCL前端框架進(jìn)行開發(fā),也可以自己寫測試界面代碼。界面效果如圖:
本示例中包含了兩個文件: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連接發(fā)生錯誤");};//連接成功建立的回調(diào)方法 websocket.onopen = (event) => { label_status.setText("已連接");} //接收到消息的回調(diào)方法 websocket.onmessage = (event) => { edit_content.setText(event.data);} //連接關(guān)閉的回調(diào)方法 websocket.onclose = (event) => { label_status.setText("已關(guān)閉");}}button1.Refresh();var closeButton = new HtmlButton(form);closeButton.left = 500;closeButton.top = 50;closeButton.width = 100;closeButton.height = 30;closeButton.text = "關(guān)閉"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 = "服務(wù)器";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 = "發(fā)送"button2.onclick = function () {}button2.Refresh();var label2 = new HtmlLabel(form);label2.text = "發(fā)送內(nèi)容";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 = "收到內(nèi)容";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>
運(yùn)行的效果:
四、兩個客戶端通訊
在真實(shí)場景中是進(jìn)行消息推送。我們在csdnProject工程進(jìn)行以下先改:
1、增加一個api接口
這個消息流的邏輯是:開放一個api接口,用戶調(diào)用接口后向服務(wù)器發(fā)送websocket消息。在action組件中進(jìn)行對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); //執(zhí)行websocketClient的Send操作。
FlowApi.execute(this,"WebSocketClient1","close",text); //執(zhí)行websocketClient的Close操作。
2、修改processWebSocket組件代碼
修改服務(wù)器的消息接收后的邏輯處理。即向指定的客戶發(fā)送消息:
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、測試消息發(fā)送
首先在SashulinMessageBroker示例中連接服務(wù)器;
然后再PostMan中發(fā)送消息:
SMB示例中收到來自于postman的消息:
結(jié)束語:應(yīng)用于生產(chǎn)環(huán)境中會更復(fù)雜,但核心點(diǎn)還是在ProcessMessage組件這里,把消息推送何處?推送幾次?這些可以做成策略。目前我們?nèi)合⑼ㄓ嵠脚_也是按這個邏輯進(jìn)行開發(fā),在國內(nèi)西南某大型兒童醫(yī)院為例,進(jìn)行了2000個客戶端,20幾個系統(tǒng)的消息對接和眾多業(yè)務(wù)場景設(shè)計(jì),穩(wěn)定、準(zhǔn)確運(yùn)行。