欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Spring Boot+Socket實現(xiàn)與html頁面的長連接實例詳解

 更新時間:2020年07月27日 11:32:56   作者:陳彥斌  
這篇文章主要介紹了Java中Spring Boot+Socket實現(xiàn)與html頁面的長連接實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Spring Boot+Socket實現(xiàn)與html頁面的長連接,客戶端給服務器端發(fā)消息,服務器給客戶端輪詢發(fā)送消息,附案例源碼

功能介紹

客戶端給所有在線用戶發(fā)送消息客戶端給指定在線用戶發(fā)送消息服務器給客戶端發(fā)送消息(輪詢方式)

注意:socket只是實現(xiàn)一些簡單的功能,具體的還需根據(jù)自身情況,代碼稍微改造下

項目搭建

項目結(jié)構(gòu)圖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.2.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.cyb</groupId>
 <artifactId>socket_test</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>socket_test</name>
 <description>Demo project for Spring Boot</description>

 <properties>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <!-- springboot websocket -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>
  <!--guava依賴-->
  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>18.0</version>
  </dependency>
  <!--fastjson依賴-->
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.46</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
   <exclusions>
    <exclusion>
     <groupId>org.junit.vintage</groupId>
     <artifactId>junit-vintage-engine</artifactId>
    </exclusion>
   </exclusions>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>

</project>

appliccation.properties

SocketTestApplication.java(Spring Boot啟動類)

WebSocketStompConfig.java

package com.cyb.socket.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketStompConfig {
 //這個bean的注冊,用于掃描帶有@ServerEndpoint的注解成為websocket ,如果你使用外置的tomcat就不需要該配置文件
 @Bean
 public ServerEndpointExporter serverEndpointExporter()
 {
  return new ServerEndpointExporter();
 }
}

WebSocket.java(Socket核心類)

package com.cyb.socket.websocket;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @Author:陳彥斌
 * @Description:Socket核心類
 * @Date: 2020-07-26
 */

@Component
@ServerEndpoint(value = "/connectWebSocket/{userId}")
public class WebSocket {

 private Logger logger = LoggerFactory.getLogger(this.getClass());
 /**
  * 在線人數(shù)
  */
 public static int onlineNumber = 0;
 /**
  * 以用戶的姓名為key,WebSocket為對象保存起來
  */
 private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
 /**
  * 會話
  */
 private Session session;
 /**
  * 用戶名稱
  */
 private String userId;

 /**
  * 建立連接
  *
  * @param session
  */
 @OnOpen
 public void onOpen(@PathParam("userId") String userId, Session session) {
  onlineNumber++;
  System.out.println("現(xiàn)在來連接的客戶id:" + session.getId() + "用戶名:" + userId);
  //logger.info("現(xiàn)在來連接的客戶id:"+session.getId()+"用戶名:"+userId);
  this.userId = userId;
  this.session = session;
  System.out.println("有新連接加入! 當前在線人數(shù)" + onlineNumber);
  // logger.info("有新連接加入! 當前在線人數(shù)" + onlineNumber);
  try {
   //messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
   //先給所有人發(fā)送通知,說我上線了
   Map<String, Object> map1 = Maps.newHashMap();
   map1.put("messageType", 1);
   map1.put("userId", userId);
   sendMessageAll(JSON.toJSONString(map1), userId);

   //把自己的信息加入到map當中去
   clients.put(userId, this);
   System.out.println("有連接關閉! 當前在線人數(shù)" + onlineNumber);
   //logger.info("有連接關閉! 當前在線人數(shù)" + clients.size());
   //給自己發(fā)一條消息:告訴自己現(xiàn)在都有誰在線
   Map<String, Object> map2 = Maps.newHashMap();
   map2.put("messageType", 3);
   //移除掉自己
   Set<String> set = clients.keySet();
   map2.put("onlineUsers", set);
   sendMessageTo(JSON.toJSONString(map2), userId);
  } catch (IOException e) {
   System.out.println(userId + "上線的時候通知所有人發(fā)生了錯誤");
   //logger.info(userId+"上線的時候通知所有人發(fā)生了錯誤");
  }
 }

 @OnError
 public void onError(Session session, Throwable error) {
  //logger.info("服務端發(fā)生了錯誤"+error.getMessage());
  //error.printStackTrace();
  System.out.println("服務端發(fā)生了錯誤:" + error.getMessage());
 }

 /**
  * 連接關閉
  */
 @OnClose
 public void onClose() {
  onlineNumber--;
  //webSockets.remove(this);
  clients.remove(userId);
  try {
   //messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
   Map<String, Object> map1 = Maps.newHashMap();
   map1.put("messageType", 2);
   map1.put("onlineUsers", clients.keySet());
   map1.put("userId", userId);
   sendMessageAll(JSON.toJSONString(map1), userId);
  } catch (IOException e) {
   System.out.println(userId + "下線的時候通知所有人發(fā)生了錯誤");
   //logger.info(userId+"下線的時候通知所有人發(fā)生了錯誤");
  }
  //logger.info("有連接關閉! 當前在線人數(shù)" + onlineNumber);
  //logger.info("有連接關閉! 當前在線人數(shù)" + clients.size());
  System.out.println("有連接關閉! 當前在線人數(shù)" + onlineNumber);
 }

 /**
  * 收到客戶端的消息
  *
  * @param message 消息
  * @param session 會話
  */
 @OnMessage
 public void onMessage(String message, Session session) {
  try {
   //logger.info("來自客戶端消息:" + message+"客戶端的id是:"+session.getId());
   System.out.println("來自客戶端消息:" + message + " | 客戶端的id是:" + session.getId());
   JSONObject jsonObject = JSON.parseObject(message);
   String textMessage = jsonObject.getString("message");
   String fromuserId = jsonObject.getString("userId");
   String touserId = jsonObject.getString("to");
   //如果不是發(fā)給所有,那么就發(fā)給某一個人
   //messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
   Map<String, Object> map1 = Maps.newHashMap();
   map1.put("messageType", 4);
   map1.put("textMessage", textMessage);
   map1.put("fromuserId", fromuserId);
   if (touserId.equals("All")) {
    map1.put("touserId", "所有人");
    sendMessageAll(JSON.toJSONString(map1), fromuserId);
   } else {
    map1.put("touserId", touserId);
    System.out.println("開始推送消息給" + touserId);
    sendMessageTo(JSON.toJSONString(map1), touserId);
   }
  } catch (Exception e) {
   e.printStackTrace();
   //logger.info("發(fā)生了錯誤了");
  }

 }

 /**
  * 給指定的用戶發(fā)送消息
  *
  * @param message
  * @param TouserId
  * @throws IOException
  */
 public void sendMessageTo(String message, String TouserId) throws IOException {
  for (WebSocket item : clients.values()) {
   System.out.println("給指定的在線用戶發(fā)送消息,在線人員名單:【" + item.userId.toString() + "】發(fā)送消息:" + message);
   if (item.userId.equals(TouserId)) {
    item.session.getAsyncRemote().sendText(message);
    break;
   }
  }
 }

 /**
  * 給所有用戶發(fā)送消息
  *
  * @param message 數(shù)據(jù)
  * @param FromuserId
  * @throws IOException
  */
 public void sendMessageAll(String message, String FromuserId) throws IOException {
  for (WebSocket item : clients.values()) {
   System.out.println("給所有在線用戶發(fā)送給消息,在線人員名單:【" + item.userId.toString() + "】發(fā)送消息:" + message);
   item.session.getAsyncRemote().sendText(message);
  }
 }

 /**
  * 給所有在線用戶發(fā)送消息
  *
  * @param message 數(shù)據(jù)
  * @throws IOException
  */
 public void sendMessageAll(String message) throws IOException {
  for (WebSocket item : clients.values()) {
   System.out.println("服務器給所有在線用戶發(fā)送消息,當前在線人員為【" + item.userId.toString() + "】發(fā)送消息:" + message);
   item.session.getAsyncRemote().sendText(message);
  }
 }

 /**
  * 獲取在線用戶數(shù)
  *
  * @return
  */
 public static synchronized int getOnlineCount() {
  return onlineNumber;
 }
}

TestController.java(前端控制器)

package com.cyb.socket.websocket;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;

@Controller
@RequestMapping("testMethod")
public class TestController {
 @Autowired
 private WebSocket webSocket;

 /**
  * 給指定的在線用戶發(fā)送消息
  * @param userId
  * @param msg
  * @return
  * @throws IOException
  */
 @ResponseBody
 @GetMapping("/sendTo")
 public String sendTo(@RequestParam("userId") String userId,@RequestParam("msg") String msg) throws IOException {
  webSocket.sendMessageTo(msg,userId);
  return "推送成功";
 }

 /**
  * 給所有在線用戶發(fā)送消息
  * @param msg
  * @return
  * @throws IOException
  * @throws IOException
  */
 @ResponseBody
 @PostMapping("/sendAll")
 public String sendAll(@RequestBody String msg) throws IOException, IOException {
  webSocket.sendMessageAll(msg);
  return "推送成功";
 }
}

SocketTask.java(輪詢調(diào)度往客戶端推送消息)

package com.cyb.socket.schedule;

import com.cyb.socket.websocket.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class SocketTask {
 @Autowired
 private WebSocket webSocket;
 private SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
 //5秒輪詢一次
 @Scheduled(fixedRate = 5000)
 public void sendClientData() throws IOException {
  String msg="{\"message\":\"你好\",\"userId\":\"002\",\"to\":\"All\"}";
  webSocket.sendMessageAll(msg);
  System.out.println("消息推送時間:"+ sdf.format(new Date()));
 }
}

測試網(wǎng)頁

index.html

<!DOCTYPE HTML>
<html>
<head>
 <title>Test My WebSocket</title>
</head>
 
 
<body>
TestWebSocket
<input id="text" type="text" style="width:500px"/>
<button onclick="send()">SEND MESSAGE</button>
<button onclick="closeWebSocket()">CLOSE</button>
<div id="message"></div>
</body>
 
<script type="text/javascript">
 var websocket = null;
 
 
 //判斷當前瀏覽器是否支持WebSocket
 if('WebSocket' in window){
  //連接WebSocket節(jié)點
  websocket = new WebSocket("ws://localhost:8083/connectWebSocket/001");
 }
 else{
  alert('Not support websocket')
 }
 
 
 //連接發(fā)生錯誤的回調(diào)方法
 websocket.onerror = function(){
  setMessageInnerHTML("error");
 };
 
 
 //連接成功建立的回調(diào)方法
 websocket.onopen = function(event){
  setMessageInnerHTML("open");
 }
 
 
 //接收到消息的回調(diào)方法
 websocket.onmessage = function(event){
  setMessageInnerHTML(event.data);
 }
 
 
 //連接關閉的回調(diào)方法
 websocket.onclose = function(){
  setMessageInnerHTML("close");
 }
 
 
 //監(jiān)聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
 window.onbeforeunload = function(){
  websocket.close();
 }
 
 
 //將消息顯示在網(wǎng)頁上
 function setMessageInnerHTML(innerHTML){
  document.getElementById('message').innerHTML += innerHTML + '<br/>';
 }
 
 
 //關閉連接
 function closeWebSocket(){
  websocket.close();
 }
 
 
 //發(fā)送消息
 function send(){
  var message = document.getElementById('text').value;
  websocket.send(message);
 }
</script>
</html>

index2.html

<!DOCTYPE HTML>
<html>
<head>
 <title>Test My WebSocket</title>
</head>
 
 
<body>
TestWebSocket
<input id="text" type="text" style="width:500px" />
<button onclick="send()">SEND MESSAGE</button>
<button onclick="closeWebSocket()">CLOSE</button>
<div id="message"></div>
</body>
 
<script type="text/javascript">
 var websocket = null;
 
 
 //判斷當前瀏覽器是否支持WebSocket
 if('WebSocket' in window){
  //連接WebSocket節(jié)點
  websocket = new WebSocket("ws://localhost:8083/connectWebSocket/002");
 }
 else{
  alert('Not support websocket')
 }
 
 
 //連接發(fā)生錯誤的回調(diào)方法
 websocket.onerror = function(){
  setMessageInnerHTML("error");
 };
 
 
 //連接成功建立的回調(diào)方法
 websocket.onopen = function(event){
  setMessageInnerHTML("open");
 }
 
 
 //接收到消息的回調(diào)方法
 websocket.onmessage = function(event){
  setMessageInnerHTML(event.data);
 }
 
 
 //連接關閉的回調(diào)方法
 websocket.onclose = function(){
  setMessageInnerHTML("close");
 }
 
 
 //監(jiān)聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
 window.onbeforeunload = function(){
  websocket.close();
 }
 
 
 //將消息顯示在網(wǎng)頁上
 function setMessageInnerHTML(innerHTML){
  document.getElementById('message').innerHTML += innerHTML + '<br/>';
 }
 
 
 //關閉連接
 function closeWebSocket(){
  websocket.close();
 }
 
 
 //發(fā)送消息
 function send(){
  var message = document.getElementById('text').value;
  websocket.send(message);
 }
</script>
</html>

項目地址

鏈接:https://pan.baidu.com/s/1yiAXTkCjHac-F3S1HFyNJQ 提取碼:53tp

功能演示

客戶端給所有在線用戶發(fā)消息

客戶端給指定在線用戶發(fā)送消息

服務器給客戶端發(fā)送消息(輪詢方式)

注意需要加上這些注解

演示

通過前端控制器給指定用戶發(fā)送消息

演示

到此這篇關于Java中Spring Boot+Socket實現(xiàn)與html頁面的長連接實例詳解的文章就介紹到這了,更多相關Java Spring Boot+Socket實現(xiàn)與html頁面的長連接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論