亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

WebSocket實現(xiàn)聊天室業(yè)務

 更新時間:2020年08月06日 08:45:02   作者:小心仔  
這篇文章主要為大家詳細介紹了WebSocket實現(xiàn)聊天室業(yè)務,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

WebSocket實現(xiàn)聊天室業(yè)務的具體代碼,供大家參考,具體內(nèi)容如下

頁面效果圖

pom.xml

主要是spring-boot-starter-websocket包,websocket連接、發(fā)送信息。

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
  <dependency><!--Webjars版本定位工具-->
   <groupId>org.webjars</groupId>
   <artifactId>webjars-locator-core</artifactId>
  </dependency>
  <dependency>
   <groupId>org.webjars.npm</groupId>
   <artifactId>mdui</artifactId>
   <version>0.4.0</version>
  </dependency>
  <dependency>
   <groupId>org.webjars</groupId>
   <artifactId>jquery</artifactId>
   <version>3.3.1</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-devtools</artifactId>
   <scope>runtime</scope>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.49</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

前臺

html + js

websocket 前臺主要包括四種方法:

  • 打開連接:onopen
  • 服務端發(fā)來消息:1.廣播消息 2.更新在線人數(shù) : onmessage
  • 關閉連接 :onclose
  • 通信失敗 :onerror
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <title>WebSocket簡單聊天室</title>
 <meta charset="utf-8" name="viewport" content="width=device-width">
 <link rel="stylesheet" th:href="@{/webjars/mdui/dist/css/mdui.css}">
 <script th:src="@{/webjars/jquery/jquery.min.js}"></script>
 <script th:src="@{/webjars/mdui/dist/js/mdui.js}"></script>
</head>
<body class="mdui-theme-primary-indigo mdui-theme-accent-pink">

<div class="mdui-container">
 <div class="mdui-toolbar mdui-color-theme">
  <a class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">menu</i></a>
  <span class="mdui-typo-title">簡單聊天室</span>
  <div class="mdui-toolbar-spacer"></div>
  <a class="mdui-btn mdui-btn-icon"  target="_blank"><i
    class="mdui-icon material-icons">search</i></a>
  <a class="mdui-btn mdui-btn-icon" th:href="@{/}"><i
    class="mdui-icon material-icons">exit_to_app</i></a>
  <a class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">more_vert</i></a>
 </div>
</div>

<div>
 <div class="mdui-container container_text">

  <div class="mdui-row">
   <div class="mdui-col-xs-12 mdui-col-sm-6">
    <div class="mdui-col-xs-12 mdui-col-sm-10">
     <div class="mdui-textfield-floating-label" style="margin-top:15px">
      <i class="mdui-icon material-icons">歡迎:</i>
      <i class="mdui-icon" id="username" th:text="${username}"></i>
     </div>
    </div>
    <div class="mdui-col-xs-12 mdui-col-sm-10">
     <div class="mdui-textfield mdui-textfield-floating-label">
      <i class="mdui-icon material-icons">textsms</i>
      <label class="mdui-textfield-label">發(fā)送內(nèi)容</label>
      <input class="mdui-textfield-input" id="msg"/>
     </div>
     <div class="mdui-container" style="padding:20px 35px">
      <button class="mdui-btn mdui-color-theme-accent mdui-ripple"
        onclick="sendMsgToServer()">發(fā)送 (enter)
      </button>
      <button class="mdui-btn mdui-color-theme mdui-ripple"
        onclick="clearMsg()">清屏
      </button>
     </div>
    </div>
   </div>

   <div class="mdui-col-xs-6 mdui-col-sm-5" style="padding:10px 0">
    <div class="mdui-chip">
     <span class="mdui-chip-icon mdui-color-blue">
      <i class="mdui-icon material-icons">&#xe420;</i></span>
     <span class="mdui-chip-title">聊天內(nèi)容</span>
    </div>

    <div class="mdui-chip">
     <span class="mdui-chip-icon mdui-color-blue">
      <i class="mdui-icon material-icons">face</i></span>
     <span class="mdui-chip-title">在線人數(shù)</span>
     <span class="mdui-chip-title chat-num">0</span>
    </div>
    <div class="message-container">

    </div>
   </div>

  </div>
 </div>
</div>

<script th:inline="javascript">

 /**
  * WebSocket客戶端
  *
  * 使用說明:
  * 1、WebSocket客戶端通過回調(diào)函數(shù)來接收服務端消息。例如:webSocket.onmessage
  * 2、WebSocket客戶端通過send方法來發(fā)送消息給服務端。例如:webSocket.send();
  */
 function getWebSocket() {
  /**
   * WebSocket客戶端 PS:URL開頭表示W(wǎng)ebSocket協(xié)議 中間是域名端口 結(jié)尾是服務端映射地址
   */
  var webSocket = new WebSocket(/*[[${webSocketUrl}]]*/ 'ws://localhost:8080/chat');
  /**
   * 當服務端打開連接
   */
  webSocket.onopen = function (event) {
   console.log('WebSocket打開連接');
  };

  /**
   * 當服務端發(fā)來消息:1.廣播消息 2.更新在線人數(shù)
   */
  webSocket.onmessage = function (event) {
   console.log('WebSocket收到消息:%c' + event.data, 'color:green');
   //獲取服務端消息
   var message = JSON.parse(event.data) || {};
   var $messageContainer = $('.message-container');
   //喉嚨發(fā)炎
   if (message.type === 'SPEAK') {
    $messageContainer.append(
     '<div class="mdui-card" style="margin: 10px 0;">' +
     '<div class="mdui-card-primary">' +
     '<div class="mdui-card-content message-content">' + message.username + ":" + message.msg + '</div>' +
     '</div></div>');
   }
   $('.chat-num').text(message.onlineCount);
   //防止刷屏
   var $cards = $messageContainer.children('.mdui-card:visible').toArray();
   if ($cards.length > 5) {
    $cards.forEach(function (item, index) {
     index < $cards.length - 5 && $(item).slideUp('fast');
    });
   }
  };

  /**
   * 關閉連接
   */
  webSocket.onclose = function (event) {
   console.log('WebSocket關閉連接');
  };

  /**
   * 通信失敗
   */
  webSocket.onerror = function (event) {
   console.log('WebSocket發(fā)生異常');

  };
  return webSocket;
 }

 var webSocket = getWebSocket();


 /**
  * 通過WebSocket對象發(fā)送消息給服務端
  */
 function sendMsgToServer() {
  var $message = $('#msg');
  if ($message.val()) {
   webSocket.send(JSON.stringify({username: $('#username').text(), msg: $message.val()}));
   $message.val(null);
  }

 }

 /**
  * 清屏
  */
 function clearMsg() {
  $(".message-container").empty();
 }

 /**
  * 使用ENTER發(fā)送消息
  */
 document.onkeydown = function (event) {
  var e = event || window.event || arguments.callee.caller.arguments[0];
  e.keyCode === 13 && sendMsgToServer();
 };


</script>

</body>
</html>

后臺

WebSocketChatApplication - 啟動類

@SpringBootApplication
@RestController
public class WebSocketChatApplication {

 /**
  * 登陸界面
  */
 @GetMapping("/")
 public ModelAndView login() {
  return new ModelAndView("/login");
 }

 /**
  * 聊天界面
  */
 @GetMapping("/index")
 public ModelAndView index(String username, String password, HttpServletRequest request) throws UnknownHostException {
  if (StringUtils.isEmpty(username)) {
   username = "匿名用戶";
  }
  ModelAndView mav = new ModelAndView("/chat");
  mav.addObject("username", username);
  mav.addObject("webSocketUrl", "ws://"+InetAddress.getLocalHost().getHostAddress()+":"+request.getServerPort()+request.getContextPath()+"/chat");
  return mav;
 }

 public static void main(String[] args) {
  SpringApplication.run(WebSocketChatApplication.class, args);
 }
}

WebSocketConfig - WebSocket配置類

@Configuration
public class WebSocketConfig {

 /**
  * 用于掃描和注冊所有攜帶ServerEndPoint注解的實例。
  * <p>
  * PS:若部署到外部容器 則無需提供此類。
  */
 @Bean
 public ServerEndpointExporter serverEndpointExporter() {

  return new ServerEndpointExporter();
 }
}

Message - 封裝信息類

/**
 * WebSocket 聊天消息類
 */
public class Message {

 public static final String ENTER = "ENTER";
 public static final String SPEAK = "SPEAK";
 public static final String QUIT = "QUIT";

 private String type;//消息類型

 private String username; //發(fā)送人

 private String msg; //發(fā)送消息

 private int onlineCount; //在線用戶數(shù)

 public static String jsonStr(String type, String username, String msg, int onlineTotal) {
  return JSON.toJSONString(new Message(type, username, msg, onlineTotal));
 }

 public Message(String type, String username, String msg, int onlineCount) {
  this.type = type;
  this.username = username;
  this.msg = msg;
  this.onlineCount = onlineCount;
 }

 public static String getENTER() {
  return ENTER;
 }

 public static String getSPEAK() {
  return SPEAK;
 }

 public static String getQUIT() {
  return QUIT;
 }

 public String getType() {
  return type;
 }

 public void setType(String type) {
  this.type = type;
 }

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public String getMsg() {
  return msg;
 }

 public void setMsg(String msg) {
  this.msg = msg;
 }

 public int getOnlineCount() {
  return onlineCount;
 }

 public void setOnlineCount(int onlineCount) {
  this.onlineCount = onlineCount;
 }
}

WebSocketChatServer - 聊天服務端

前臺對應的四種傳輸,后臺進行處理操作

/**
 * WebSocket 聊天服務端
 *
 * @see ServerEndpoint WebSocket服務端 需指定端點的訪問路徑
 * @see Session WebSocket會話對象 通過它給客戶端發(fā)送消息
 */

@Component
@ServerEndpoint("/chat")
public class WebSocketChatServer {

 /**
  * 全部在線會話 PS: 基于場景考慮 這里使用線程安全的Map存儲會話對象。
  */
 private static Map<String, Session> onlineSessions = new ConcurrentHashMap<>();


 /**
  * 當客戶端打開連接:1.添加會話對象 2.更新在線人數(shù)
  */
 @OnOpen
 public void onOpen(Session session) {
  onlineSessions.put(session.getId(), session);
  sendMessageToAll(Message.jsonStr(Message.ENTER, "", "", onlineSessions.size()));
 }

 /**
  * 當客戶端發(fā)送消息:1.獲取它的用戶名和消息 2.發(fā)送消息給所有人
  * <p>
  * PS: 這里約定傳遞的消息為JSON字符串 方便傳遞更多參數(shù)!
  */
 @OnMessage
 public void onMessage(Session session, String jsonStr) {
  Message message = JSON.parseObject(jsonStr, Message.class);
  sendMessageToAll(Message.jsonStr(Message.SPEAK, message.getUsername(), message.getMsg(), onlineSessions.size()));
 }

 /**
  * 當關閉連接:1.移除會話對象 2.更新在線人數(shù)
  */
 @OnClose
 public void onClose(Session session) {
  onlineSessions.remove(session.getId());
  sendMessageToAll(Message.jsonStr(Message.QUIT, "", "", onlineSessions.size()));
 }

 /**
  * 當通信發(fā)生異常:打印錯誤日志
  */
 @OnError
 public void onError(Session session, Throwable error) {
  error.printStackTrace();
 }

 /**
  * 公共方法:發(fā)送信息給所有人
  */
 private static void sendMessageToAll(String msg) {
  onlineSessions.forEach((id, session) -> {
   try {
    session.getBasicRemote().sendText(msg);
   } catch (IOException e) {
    e.printStackTrace();
   }
  });
 }

}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Quartz高可用定時任務的快速上手指南

    Quartz高可用定時任務的快速上手指南

    Quartz的分布式策略就是一種以數(shù)據(jù)庫作為邊界資源的并發(fā)策略,每個節(jié)點都遵守相同的操作規(guī)范,使得對數(shù)據(jù)庫的操作可以串行執(zhí)行,而不同名稱的調(diào)度器又可以互不影響的并行運行,下面這篇文章主要介紹了Quartz高可用定時任務快速上手的相關資料,需要的朋友可以參考下
    2022-04-04
  • 深入學習java并發(fā)包ConcurrentHashMap源碼

    深入學習java并發(fā)包ConcurrentHashMap源碼

    這篇文章主要介紹了深入學習java并發(fā)包ConcurrentHashMap源碼,整個 ConcurrentHashMap 由一個個 Segment 組成,Segment 代表”部分“或”一段“的意思,所以很多地方都會將其描述為分段鎖。,需要的朋友可以參考下
    2019-06-06
  • 深入剖析Java工廠模式讓你的代碼更靈活

    深入剖析Java工廠模式讓你的代碼更靈活

    Java工廠模式是一種創(chuàng)建對象的設計模式,它可以在不暴露對象創(chuàng)建邏輯的情況下,將對象的創(chuàng)建委托給子類或者其他對象。本文就來深入剖析一下Java工廠模式是如何讓你的代碼更靈活、可擴展、易維護的
    2023-05-05
  • Spring中使用Async進行異步功能開發(fā)實戰(zhàn)示例(大文件上傳為例)

    Spring中使用Async進行異步功能開發(fā)實戰(zhàn)示例(大文件上傳為例)

    本文以大文件上傳為例,首先講解在未進行程序異步化時,程序的運行機制和具體表現(xiàn),然后講解如何進行異步化的改造,讓程序進行異步執(zhí)行,通過本文不僅能讓你掌握如何進行Event的事件開發(fā),同時還能掌握在Spring中如何進行異步開發(fā),熟悉@Async的具體用法,感興趣的朋友一起看看吧
    2024-08-08
  • 通過簡單步驟實現(xiàn)SpringMVC文件上傳

    通過簡單步驟實現(xiàn)SpringMVC文件上傳

    這篇文章主要介紹了通過簡單步驟實現(xiàn)SpringMVC文件上傳,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解

    java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序,結(jié)合具體實例形式分析了java樹形選擇排序的原理、實現(xiàn)技巧與相關注意事項,需要的朋友可以參考下
    2017-05-05
  • Java利用跳躍表解決雙重隊列問題詳解

    Java利用跳躍表解決雙重隊列問題詳解

    這篇文章主要為大家詳細介紹了Java如何利用跳躍表來解決雙重隊列的問題。本文通過一個簡單的例題進行了講解,感興趣的小伙伴可以了解一下
    2022-12-12
  • hibernate測試時遇到的幾個異常及解決方法匯總

    hibernate測試時遇到的幾個異常及解決方法匯總

    今天小編就為大家分享一篇關于hibernate測試時遇到的幾個異常及解決方法匯總,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java正則驗證正整數(shù)的方法分析【測試可用】

    Java正則驗證正整數(shù)的方法分析【測試可用】

    這篇文章主要介紹了Java正則驗證正整數(shù)的方法,結(jié)合實例形式對比分析了java針對正整數(shù)的驗證方法及相關注意事項,需要的朋友可以參考下
    2017-08-08
  • springboot?serviceImpl初始化注入對象實現(xiàn)方式

    springboot?serviceImpl初始化注入對象實現(xiàn)方式

    這篇文章主要介紹了springboot?serviceImpl初始化注入對象實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論