最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WebSocket實(shí)現(xiàn)Web聊天室功能

 更新時(shí)間:2018年08月30日 14:37:22   作者:DOLFAMINGO  
這篇文章主要為大家詳細(xì)介紹了WebSocket實(shí)現(xiàn)Web聊天室功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文為大家分享了WebSocket實(shí)現(xiàn)Web聊天室的具體代碼,供大家參考,具體內(nèi)容如下

一.客戶端

JS代碼如下:

/*
 *   這部分js將websocket封裝起來
 */
  var websocket = null;
  //判斷當(dāng)前瀏覽器是否支持WebSocket
  if ('WebSocket' in window) {
    websocket = new WebSocket("ws://localhost:8080/GoodMan/ChatService");
  }
  else {
    alert('當(dāng)前瀏覽器 Not support websocket')
  }
  
   //連接成功建立的回調(diào)方法
  websocket.onopen = function () {
    alert("WebSocket連接成功");
  }

  //連接發(fā)生錯(cuò)誤的回調(diào)方法
  websocket.onerror = function () {
    alert("WebSocket連接發(fā)生錯(cuò)誤");
  };
  
   //發(fā)送消息
  function sendMess(content) {
     var json ="{'username':'"+'${sessionScope.username }'+"', 'content':'"+content+"'}";
    websocket.send(json);
  }

  //接收到消息的回調(diào)方法
  websocket.onmessage = function (event) {
    var jsonString = event.data;    //接收到的信息存放在event.data中
    var data = JSON.parse(jsonString);  //將json字符串轉(zhuǎn)換成js對(duì)象
    // 然后輸出data
  }

   //連接關(guān)閉的回調(diào)方法
  websocket.onclose = function () {
    alert("WebSocket連接關(guān)閉");
  }

  //監(jiān)聽窗口關(guān)閉事件,當(dāng)窗口關(guān)閉時(shí),主動(dòng)去關(guān)閉websocket連接,防止連接還沒斷開就關(guān)閉窗口,server端會(huì)拋異常。
  window.onbeforeunload = function () {
    closeWebSocket();
  }

  //關(guān)閉WebSocket連接
  function closeWebSocket() {
    websocket.close();
  }

二.服務(wù)器

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import com.google.gson.Gson;

class Mess{    //封裝一條消息
  private String username;
  private String content;
  private String date;
  public Mess(String username, String content, String date) {
    super();
    this.username = username;
    this.content = content;
    this.date = date;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getContent() {
    return content;
  }
  public void setContent(String content) {
    this.content = content;
  }
  public String getDate() {
    return date;
  }
  public void setDate(String date) {
    this.date = date;
  }
}

@ServerEndpoint("/ChatService")
public class ChatService {      //每進(jìn)入一個(gè)用戶,就新建一個(gè)ChatService對(duì)象
  
  private static int onlineCount = 0; //靜態(tài)變量, 用來記錄當(dāng)前在線連接數(shù)
  private static Set<ChatService> webSocketSet = new HashSet<>();    //靜態(tài)變量,用來存放在線用戶
  private Session session;   //用于存儲(chǔ)與該用戶的會(huì)話,要通過它來給客戶端發(fā)送數(shù)據(jù)

  /**
   * 連接建立成功調(diào)用的方法
   * @param session 可選的參數(shù)。session為與某個(gè)客戶端的連接會(huì)話,需要通過它來給客戶端發(fā)送數(shù)據(jù)
   */
  @OnOpen
  public void onOpen(Session session){
    this.session = session;
    webSocketSet.add(this);   //加入set中
    addOnlineCount();      //在線數(shù)加1
    System.out.println("有新連接加入!當(dāng)前在線人數(shù)為" + getOnlineCount());
  }
  
  /**
   * 連接關(guān)閉調(diào)用的方法
   */
  @OnClose
  public void onClose(){
    webSocketSet.remove(this); //從set中刪除
    subOnlineCount();      //在線數(shù)減1
    System.out.println("有一連接關(guān)閉!當(dāng)前在線人數(shù)為" + getOnlineCount());
  }

  /**
   * 收到客戶端消息后調(diào)用的方法
   * @param message 客戶端發(fā)送過來的消息
   * @param session 可選的參數(shù)
   */
  @OnMessage
  public void onMessage(String data, Session session) {
    Mess mess = new Gson().fromJson(data, Mess.class);
    System.out.printf("來%s的消息:%s\n", mess.getUsername(), mess.getContent());
    //群發(fā)消息
    for(ChatService item: webSocketSet){
      try {
        item.sendMessage(mess);
      } catch (IOException e) {
        e.printStackTrace();
        continue;
      }
    }
  }
  
  /**
   * 發(fā)生錯(cuò)誤時(shí)調(diào)用
   * @param session
   * @param error
   */
  @OnError
  public void onError(Session session, Throwable error){
    System.out.println("發(fā)生錯(cuò)誤");
    error.printStackTrace();
  }

  //以下為輔助函數(shù)
  public void sendMessage(Mess mess) throws IOException{

    String datatime = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    mess.setDate(datatime);
    String jsonInfo = new Gson().toJson(mess);    //將消息對(duì)象轉(zhuǎn)換成json字符串
    this.session.getAsyncRemote().sendText(jsonInfo); //通過session異步地將信息發(fā)送到客戶端上
  }

  public static synchronized int getOnlineCount() {
    return onlineCount;
  }

  public static synchronized void addOnlineCount() {
    ChatService.onlineCount++;
  }

  public static synchronized void subOnlineCount() {
    ChatService.onlineCount--;
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++實(shí)現(xiàn)掃雷游戲示例講解

    C++實(shí)現(xiàn)掃雷游戲示例講解

    這篇文章主要介紹了C++實(shí)現(xiàn)掃雷游戲示例講解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot讀取properties文件配置項(xiàng)過程解析

    SpringBoot讀取properties文件配置項(xiàng)過程解析

    這篇文章主要介紹了SpringBoot讀取properties文件配置項(xiàng)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word

    基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word

    這篇文章主要介紹了基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • JavaSE實(shí)現(xiàn)文件壓縮與解壓縮的技巧分享

    JavaSE實(shí)現(xiàn)文件壓縮與解壓縮的技巧分享

    我們?cè)谌粘?shí)際開發(fā)中,對(duì)于文件壓縮和解壓縮場(chǎng)景,是非常常見的操作,本文詳細(xì)介紹JavaSE中文件壓縮和解壓縮的實(shí)現(xiàn)方法,包括源代碼解析、應(yīng)用場(chǎng)景案例、優(yōu)缺點(diǎn)分析、案例演示、文末總結(jié)等等,請(qǐng)同學(xué)們耐心閱讀
    2024-03-03
  • Java Maven依賴傳遞,可選依賴,排除依賴詳解

    Java Maven依賴傳遞,可選依賴,排除依賴詳解

    這篇文章主要介紹了Java Maven依賴傳遞,可選依賴,排除依賴詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • java中l(wèi)ist使用時(shí)需避免的場(chǎng)景總結(jié)

    java中l(wèi)ist使用時(shí)需避免的場(chǎng)景總結(jié)

    眾所周知,Java為開發(fā)者提供了多種集合類的實(shí)現(xiàn),其中幾乎所有業(yè)務(wù)代碼都需要用到List,但List的錯(cuò)誤使用也會(huì)導(dǎo)致諸多問題,所以本文我們就來看一看幾個(gè)錯(cuò)誤使用List的場(chǎng)景吧
    2023-10-10
  • Spring boot整合Mybatis-plus過程解析

    Spring boot整合Mybatis-plus過程解析

    這篇文章主要介紹了Spring boot整合Mybatis-plus過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 解決ObjectMapper序列換Map時(shí)候的坑

    解決ObjectMapper序列換Map時(shí)候的坑

    這篇文章主要介紹了解決ObjectMapper序列換Map時(shí)候的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java模擬多線程http請(qǐng)求代碼分享

    java模擬多線程http請(qǐng)求代碼分享

    本篇文章給大家分享了java模擬多線程http請(qǐng)求的相關(guān)實(shí)例代碼,對(duì)此有需要的可以跟著測(cè)試下。
    2018-05-05
  • spring task @Scheduled注解各參數(shù)的用法

    spring task @Scheduled注解各參數(shù)的用法

    這篇文章主要介紹了spring task @Scheduled注解各參數(shù)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評(píng)論

吐鲁番市| 三原县| 邳州市| 措勤县| 北流市| 康定县| 涟源市| 柏乡县| 哈巴河县| 临沂市| 外汇| 南涧| 新河县| 东山县| 淮滨县| 太康县| 民县| 德清县| 阜新市| 兰西县| 唐河县| 广饶县| 白城市| 光泽县| 新余市| 宝坻区| 永修县| 新巴尔虎左旗| 文昌市| 天门市| 仁怀市| 广昌县| 修文县| 安阳市| 信宜市| 德江县| 禹州市| 宁德市| 沿河| 河南省| 大庆市|