国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot+WebSocket實(shí)現(xiàn)服務(wù)端、客戶端

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot+WebSocket實(shí)現(xiàn)服務(wù)端、客戶端。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、引言

小編最近一直在使用springboot框架開發(fā)項(xiàng)目,畢竟現(xiàn)在很多公司都在采用此框架,之后小編也會(huì)陸續(xù)寫關(guān)于springboot開發(fā)常用功能的文章。

什么場(chǎng)景下會(huì)要使用到websocket的呢?

websocket主要功能就是實(shí)現(xiàn)網(wǎng)絡(luò)通訊,比如說最經(jīng)典的客服聊天窗口、您有新的消息通知,或者是項(xiàng)目與項(xiàng)目之間的通訊,都可以采用websocket來實(shí)現(xiàn)。

二、websocket介紹

百度百科介紹:WebSokcet

在公司實(shí)際使用websocket開發(fā),一般來都是這樣的架構(gòu),首先websocket服務(wù)端是一個(gè)單獨(dú)的項(xiàng)目,其他需要通訊的項(xiàng)目都是以客戶端來連接,由服務(wù)端控制消息的發(fā)送方式(群發(fā)、指定發(fā)送)。但是也會(huì)有服務(wù)端、客戶端在同一個(gè)項(xiàng)目當(dāng)中,具體看項(xiàng)目怎么使用。

本文呢,采用的是服務(wù)端與客戶端分離來實(shí)現(xiàn),包括使用springboot搭建websokcet服務(wù)端、html5客戶端、springboot后臺(tái)客戶端, 具體看下面代碼。

三、服務(wù)端實(shí)現(xiàn)

*步驟一*:springboot底層幫我們自動(dòng)配置了websokcet,引入maven依賴

<dependency>
????<groupId>org.springframework.boot</groupId>
????<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

*步驟二*:如果是你采用springboot內(nèi)置容器啟動(dòng)項(xiàng)目的,則需要配置一個(gè)Bean。如果是采用外部的容器,則可以不需要配置。

/**

?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/11?11:49
?*?@Description:?配置類
?*/
@Component
public?class?WebSocketConfig?{


????/**
?????*?ServerEndpointExporter?作用
?????*
?????*?這個(gè)Bean會(huì)自動(dòng)注冊(cè)使用@ServerEndpoint注解聲明的websocket?endpoint
?????*
?????*?@return
?????*/
????@Bean
????public?ServerEndpointExporter?serverEndpointExporter()?{
????????return?new?ServerEndpointExporter();
????}
}

*步驟三*:最后一步當(dāng)然是編寫服務(wù)端核心代碼了,其實(shí)小編不是特別想貼代碼出來,貼很多代碼影響文章可讀性。

package?com.example.socket.code;


import?lombok.extern.slf4j.Slf4j;
import?org.springframework.stereotype.Component;
import?javax.websocket.OnClose;
import?javax.websocket.OnMessage;
import?javax.websocket.OnOpen;
import?javax.websocket.Session;
import?javax.websocket.server.PathParam;
import?javax.websocket.server.ServerEndpoint;
import?java.util.concurrent.ConcurrentHashMap;


/**
?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/11?11:48
?*?@Description:?websocket?服務(wù)類
?*/

/**



?*
?*?@ServerEndpoint?這個(gè)注解有什么作用?
?*
?*?這個(gè)注解用于標(biāo)識(shí)作用在類上,它的主要功能是把當(dāng)前類標(biāo)識(shí)成一個(gè)WebSocket的服務(wù)端
?*?注解的值用戶客戶端連接訪問的URL地址
?*
?*/


@Slf4j
@Component
@ServerEndpoint("/websocket/{name}")
public?class?WebSocket?{


????/**
?????*??與某個(gè)客戶端的連接對(duì)話,需要通過它來給客戶端發(fā)送消息
?????*/
????private?Session?session;
?????/**
?????*?標(biāo)識(shí)當(dāng)前連接客戶端的用戶名
?????*/
????private?String?name;


????/**
?????*??用于存所有的連接服務(wù)的客戶端,這個(gè)對(duì)象存儲(chǔ)是安全的
?????*/
????private?static?ConcurrentHashMap<String,WebSocket>?webSocketSet?=?new?ConcurrentHashMap<>();

????@OnOpen
????public?void?OnOpen(Session?session,?@PathParam(value?=?"name")?String?name){

????????this.session?=?session;
????????this.name?=?name;
????????//?name是用來表示唯一客戶端,如果需要指定發(fā)送,需要指定發(fā)送通過name來區(qū)分
????????webSocketSet.put(name,this);

????????log.info("[WebSocket]?連接成功,當(dāng)前連接人數(shù)為:={}",webSocketSet.size());
????}




????@OnClose
????public?void?OnClose(){
????????webSocketSet.remove(this.name);
????????log.info("[WebSocket]?退出成功,當(dāng)前連接人數(shù)為:={}",webSocketSet.size());
????}



????@OnMessage
????public?void?OnMessage(String?message){
????????log.info("[WebSocket]?收到消息:{}",message);

????????//判斷是否需要指定發(fā)送,具體規(guī)則自定義
????????if(message.indexOf("TOUSER")?==?0){

????????????String?name?=?message.substring(message.indexOf("TOUSER")+6,message.indexOf(";"));
????????????AppointSending(name,message.substring(message.indexOf(";")+1,message.length()));

????????}else{

????????????GroupSending(message);
????????}

????}


????/**
?????*?群發(fā)
?????*?@param?message
?????*/
????public?void?GroupSending(String?message){
????????for?(String?name?:?webSocketSet.keySet()){
????????????try?{
????????????????webSocketSet.get(name).session.getBasicRemote().sendText(message);
????????????}catch?(Exception?e){
????????????????e.printStackTrace();
????????????}
????????}
????}



????/**
?????*?指定發(fā)送
?????*?@param?name
?????*?@param?message
?????*/
????public?void?AppointSending(String?name,String?message){
????????try?{
????????????webSocketSet.get(name).session.getBasicRemote().sendText(message);
????????}catch?(Exception?e){
????????????e.printStackTrace();
????????}
????}
}

四、客戶端實(shí)現(xiàn)

*HTML5實(shí)現(xiàn)*:以下就是核心代碼了,其實(shí)其他博客有很多,小編就不多說了。

?var?websocket?=?null;

????if('WebSocket'?in?window){
????????websocket?=?new?WebSocket("ws://192.168.2.107:8085/websocket/testname");
????}

????websocket.onopen?=?function(){
????????console.log("連接成功");
????}


????websocket.onclose?=?function(){
????????console.log("退出連接");
????}


????websocket.onmessage?=?function?(event){
????????console.log("收到消息"+event.data);
????}


????websocket.onerror?=?function(){
????????console.log("連接出錯(cuò)");
????}

????window.onbeforeunload?=?function?()?{
????????websocket.close(num);
????}

*SpringBoot后臺(tái)實(shí)現(xiàn)*:小編發(fā)現(xiàn)多數(shù)博客都是采用js來實(shí)現(xiàn)客戶端,很少有用后臺(tái)來實(shí)現(xiàn),所以小編也就寫了寫,大神請(qǐng)勿噴?。很多時(shí)候,項(xiàng)目與項(xiàng)目之間通訊也需要后臺(tái)作為客戶端來連接。

*步驟一*:首先我們要導(dǎo)入后臺(tái)連接websocket的客戶端依賴

<!--websocket作為客戶端-->

<dependency>
????<groupId>org.java-websocket</groupId>
????<artifactId>Java-WebSocket</artifactId>
????<version>1.3.5</version>
</dependency>

*步驟二*:把客戶端需要配置到springboot容器里面去,以便程序調(diào)用。

package?com.example.socket.config;

import?lombok.extern.slf4j.Slf4j;
import?org.java_websocket.client.WebSocketClient;
import?org.java_websocket.drafts.Draft_6455;
import?org.java_websocket.handshake.ServerHandshake;
import?org.springframework.context.annotation.Bean;
import?org.springframework.stereotype.Component;

import?java.net.URI;

/**
?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/11?17:38
?*?@Description:?配置websocket后臺(tái)客戶端
?*/
@Slf4j
@Component
public?class?WebSocketConfig?{
????@Bean
????public?WebSocketClient?webSocketClient()?{
????????try?{
????????????WebSocketClient?webSocketClient?=?new?WebSocketClient(new?URI("ws://localhost:8085/websocket/test"),new?Draft_6455())?{

????????????????@Override
????????????????public?void?onOpen(ServerHandshake?handshakedata)?{
????????????????????log.info("[websocket]?連接成功");
????????????????}


????????????????@Override
????????????????public?void?onMessage(String?message)?{
????????????????????log.info("[websocket]?收到消息={}",message);

????????????????}


????????????????@Override
????????????????public?void?onClose(int?code,?String?reason,?boolean?remote)?{
????????????????????log.info("[websocket]?退出連接");
????????????????}


????????????????@Override
????????????????public?void?onError(Exception?ex)?{
????????????????????log.info("[websocket]?連接錯(cuò)誤={}",ex.getMessage());
????????????????}
????????????};

????????????webSocketClient.connect();
????????????return?webSocketClient;

????????}?catch?(Exception?e)?{

????????????e.printStackTrace();

????????}

????????return?null;
????}


}

*步驟三*:使用后臺(tái)客戶端發(fā)送消息

1、首先小編寫了一個(gè)接口,里面有指定發(fā)送和群發(fā)消息兩個(gè)方法。

2、實(shí)現(xiàn)發(fā)送的接口,區(qū)分指定發(fā)送和群發(fā)由服務(wù)端來決定(小編在服務(wù)端寫了,如果帶有TOUSER標(biāo)識(shí)的,則代表需要指定發(fā)送給某個(gè)websocket客戶端)

3、最后采用get方式用瀏覽器請(qǐng)求,也能正常發(fā)送消息

package?com.example.socket.code;
/**
?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/12?10:57
?*?@Description:?websocket?接口
?*/
public?interface?WebSocketService?{

????/**
?????*?群發(fā)
?????*?@param?message
?????*/
?????void?groupSending(String?message);

????/**
?????*?指定發(fā)送
?????*?@param?name
?????*?@param?message
?????*/
?????void?appointSending(String?name,String?message);
}
package?com.example.socket.code;

import?org.java_websocket.client.WebSocketClient;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.stereotype.Component;


/**
?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/12?10:56
?*?@Description:?websocket接口實(shí)現(xiàn)類
?*/
@Component
public?class?ScoketClient?implements?WebSocketService{

????@Autowired
????private?WebSocketClient?webSocketClient;

????@Override
????public?void?groupSending(String?message)?{

????????//?這里我加了6666--?是因?yàn)槲以趇ndex.html頁面中,要拆分用戶編號(hào)和消息的標(biāo)識(shí),只是一個(gè)例子而已
????????//?在index.html會(huì)隨機(jī)生成用戶編號(hào),這里相當(dāng)于模擬頁面發(fā)送消息
????????//?實(shí)際這樣寫就行了?webSocketClient.send(message)
????????webSocketClient.send(message+"---6666");
????}

????@Override
????public?void?appointSending(String?name,?String?message)?{

????????//?這里指定發(fā)送的規(guī)則由服務(wù)端決定參數(shù)格式
????????webSocketClient.send("TOUSER"+name+";"+message);

????}
}
package?com.example.socket.chat;

import?com.example.socket.code.ScoketClient;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.RestController;

/**
?*?@Auther:?liaoshiyao
?*?@Date:?2019/1/11?16:47
?*?@Description:?測(cè)試后臺(tái)websocket客戶端

?*/
@RestController
@RequestMapping("/websocket")
public?class?IndexController?{


????@Autowired
????private?ScoketClient?webScoketClient;


????@GetMapping("/sendMessage")
????public?String?sendMessage(String?message){
????????webScoketClient.groupSending(message);
????????return?message;
????}
}

五、最后

其實(shí),貼了這么多大一片的代碼,感覺上影響了博客的美觀,也不便于瀏覽,如果沒看懂小伙伴,可以下載源碼看下。

里面一共兩個(gè)項(xiàng)目,服務(wù)端、客戶端(html5客戶端、后臺(tái)客戶端),是一個(gè)網(wǎng)頁群聊的小案例。

https://download.csdn.net/download/weixin_38111957/10912384

*祝大家學(xué)習(xí)愉快~~~*

六、針對(duì)評(píng)論區(qū)的小伙伴提出的疑點(diǎn)進(jìn)行解答

看了小伙伴提出的疑問,小編也是非常認(rèn)可的,如果是單例的情況下,這個(gè)對(duì)象的值都會(huì)被修改。

小編就抽了時(shí)間Debug了一下,經(jīng)過下圖也可以反映出,能夠看出,webSokcetSet中存在三個(gè)成員,并且vlaue值都是不同的,所以在這里沒有出現(xiàn)對(duì)象改變而把之前對(duì)象改變的現(xiàn)象。

服務(wù)端這樣寫是沒問題的。

springboot websocket客戶端,架構(gòu),spring boot,websocket,后端文章來源地址http://www.zghlxwxcb.cn/news/detail-639728.html

緊接著,小編寫了一個(gè)測(cè)試類,代碼如下,經(jīng)過測(cè)試輸出的結(jié)果和小伙伴提出的疑點(diǎn)是一致的。

最后總結(jié):這位小伙伴提出的觀點(diǎn)確實(shí)是正確的,但是在實(shí)際WebSocket服務(wù)端案例中為什么沒有出現(xiàn)這種情況,當(dāng)WebSokcet這個(gè)類標(biāo)識(shí)為服務(wù)端的時(shí)候,每當(dāng)有新的連接請(qǐng)求,這個(gè)類都是不同的對(duì)象,并非單例。

這里也感謝“煙花蘇柳”所提出的問題。

import?com.alibaba.fastjson.JSON;
import?java.util.concurrent.ConcurrentHashMap;

/**

?*?@Auther:?IT賤男

?*?@Date:?2018/11/1?16:15

?*?@Description:

?*/

public?class?TestMain?{

????/**

?????*?用于存所有的連接服務(wù)的客戶端,這個(gè)對(duì)象存儲(chǔ)是安全的

?????*/

????private?static?ConcurrentHashMap<String,?Student>?webSocketSet?=?new?ConcurrentHashMap<>();


????public?static?void?main(String[]?args)?{

????????Student?student?=?Student.getStudent();

????????student.name?=?"張三";

????????webSocketSet.put("1",?student);

????????Student?students?=?Student.getStudent();
????????students.name?=?"李四";

????????webSocketSet.put("2",?students);

????????System.out.println(JSON.toJSON(webSocketSet));
????}
}

/**

?*?提供一個(gè)單例類

?*/

class?Student?{

????public?String?name;

????private?Student()?{

????}

????private?static?final?Student?student?=?new?Student();


????public?static?Student?getStudent()?{
????????return?student;
????}

}

{"1":{"name":"李四"},"2":{"name":"李四"}}

springboot websocket客戶端,架構(gòu),spring boot,websocket,后端

到了這里,關(guān)于SpringBoot+WebSocket實(shí)現(xiàn)服務(wù)端、客戶端的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SpringBoot WebSocket做客戶端

    常見的都是springboot應(yīng)用做服務(wù),前端頁面做客戶端,進(jìn)行websocket通信進(jìn)行數(shù)據(jù)傳輸交互。但其實(shí)springboot服務(wù)也能做客戶端去連接別的webSocket服務(wù)提供者。 剛好最近在項(xiàng)目中就使用到了,需求背景大概就是我們作為一個(gè)java段應(yīng)用需要和一個(gè)C語言應(yīng)用進(jìn)行通信。在項(xiàng)目需求及

    2024年02月11日
    瀏覽(24)
  • 快速搭建springboot websocket客戶端

    快速搭建springboot websocket客戶端

    WebSocket 是 HTML5 開始提供的一種在單個(gè) TCP 連接上進(jìn)行全雙工通訊的協(xié)議。 HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時(shí)地進(jìn)行通訊。 HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時(shí)地進(jìn)行通訊。 瀏覽器通過 JavaSc

    2024年02月06日
    瀏覽(25)
  • SpringBoot2.0集成WebSocket,多客戶端

    適用于單客戶端,一個(gè)賬號(hào)登陸一個(gè)客戶端,登陸多個(gè)客戶端會(huì)報(bào)錯(cuò) The remote endpoint was in state [TEXT_FULL_WRITING]? 這是因?yàn)榇藭r(shí)的session是不同的,只能鎖住一個(gè)session,解決此問題的方法把全局靜態(tài)對(duì)象鎖住,因?yàn)橘~號(hào)是唯一的

    2024年02月10日
    瀏覽(23)
  • Springboot 集成WebSocket作為客戶端,含重連接功能,開箱即用

    使用演示 只需要init后調(diào)用sendMessage方法即可,做到開箱即用。內(nèi)部封裝了失敗重連接、斷線重連接等功能。 基于Springboot工程 引入websocket依賴 開箱即用的工具類

    2024年02月04日
    瀏覽(36)
  • springboot集成webstock實(shí)戰(zhàn):服務(wù)端數(shù)據(jù)推送數(shù)據(jù)到客戶端實(shí)現(xiàn)實(shí)時(shí)刷新

    springboot集成webstock實(shí)戰(zhàn):服務(wù)端數(shù)據(jù)推送數(shù)據(jù)到客戶端實(shí)現(xiàn)實(shí)時(shí)刷新

    ????之前介紹過springboot集成webstock方式,具體參考: springboot集成websocket實(shí)戰(zhàn):站內(nèi)消息實(shí)時(shí)推送 這里補(bǔ)充另外一個(gè)使用webstock的場(chǎng)景,方便其他同學(xué)理解和使用,廢話不多說了,直接開始!簡單介紹一下業(yè)務(wù)場(chǎng)景: ????現(xiàn)在有一個(gè)投票活動(dòng),活動(dòng)詳情中會(huì)顯示投票活動(dòng)的參與人數(shù)、訪

    2024年02月08日
    瀏覽(48)
  • netty學(xué)習(xí)(3):SpringBoot整合netty實(shí)現(xiàn)多個(gè)客戶端與服務(wù)器通信

    netty學(xué)習(xí)(3):SpringBoot整合netty實(shí)現(xiàn)多個(gè)客戶端與服務(wù)器通信

    創(chuàng)建一個(gè)SpringBoot工程,然后創(chuàng)建三個(gè)子模塊 整體工程目錄:一個(gè)server服務(wù)(netty服務(wù)器),兩個(gè)client服務(wù)(netty客戶端) pom文件引入netty依賴,springboot依賴 NettySpringBootApplication NettyServiceHandler SocketInitializer NettyServer NettyStartListener application.yml Client1 NettyClientHandler SocketInitializ

    2024年02月11日
    瀏覽(56)
  • SpringBoot中使用Netty實(shí)現(xiàn)TCP通訊,服務(wù)器主動(dòng)向客戶端發(fā)送數(shù)據(jù)

    SpringBoot中使用Netty實(shí)現(xiàn)TCP通訊,服務(wù)器主動(dòng)向客戶端發(fā)送數(shù)據(jù)

    Springboot項(xiàng)目的web服務(wù)后臺(tái),web服務(wù)運(yùn)行在9100端口。 后臺(tái)使用netty實(shí)現(xiàn)了TCP服務(wù),運(yùn)行在8000端口。 啟動(dòng)截圖如下: 啟動(dòng)類修改: 服務(wù)器查看當(dāng)前所有連接的客戶端 ?服務(wù)器獲取到所有客戶單的ip地址及端口號(hào)后,即可通過其給指定客戶端發(fā)送數(shù)據(jù) ?

    2024年02月11日
    瀏覽(29)
  • SpringBoot+CAS整合服務(wù)端和客戶端實(shí)現(xiàn)SSO單點(diǎn)登錄與登出快速入門上手

    SpringBoot+CAS整合服務(wù)端和客戶端實(shí)現(xiàn)SSO單點(diǎn)登錄與登出快速入門上手

    教學(xué)講解視頻地址:視頻地址 因?yàn)镃AS支持HTTP請(qǐng)求訪問,而我們是快速入門上手視頻,所以這期教程就不教大家如何配置HTTPS了,如果需要使用HTTPS,可以參考其他博客去云服務(wù)器申請(qǐng)證書或者使用JDK自行生成一個(gè)證書。 下載CAS Server(直接下載壓縮包就可以) 這里我們用的是

    2024年02月02日
    瀏覽(18)
  • Java實(shí)現(xiàn)WebSocket客戶端和服務(wù)端(簡單版)

    Java實(shí)現(xiàn)WebSocket客戶端和服務(wù)端(簡單版)

    天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物。 每個(gè)人都有惰性,但不斷學(xué)習(xí)是好好生活的根本,共勉! 文章均為學(xué)習(xí)整理筆記,分享記錄為主,如有錯(cuò)誤請(qǐng)指正,共同學(xué)習(xí)進(jìn)步。 寫在前面: WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。 WebSocket通信協(xié)議于

    2024年02月08日
    瀏覽(35)
  • C++實(shí)現(xiàn)WebSocket通信(服務(wù)端和客戶端)

    C++實(shí)現(xiàn)WebSocket通信(服務(wù)端和客戶端)

    天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物。 每個(gè)人都有惰性,但不斷學(xué)習(xí)是好好生活的根本,共勉! 文章均為學(xué)習(xí)整理筆記,分享記錄為主,如有錯(cuò)誤請(qǐng)指正,共同學(xué)習(xí)進(jìn)步。 這里單純是個(gè)人總結(jié),如需更官方更準(zhǔn)確的websocket介紹可百度 websocket是一種即時(shí)通訊協(xié)

    2024年02月09日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包