WebSocket实现Web聊天室功能

 更新时间:2018年08月30日 14:37:22   作者:DOLFAMINGO  
这篇文章主要为大家详细介绍了WebSocket实现Web聊天室功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了WebSocket实现Web聊天室的具体代码,供大家参考,具体内容如下

一.客户端

JS代码如下:

/*
 *   这部分js将websocket封装起来
 */
  var websocket = null;
  //判断当前浏览器是否支持WebSocket
  if ('WebSocket' in window) {
    websocket = new WebSocket("ws://localhost:8080/GoodMan/ChatService");
  }
  else {
    alert('当前浏览器 Not support websocket')
  }
  
   //连接成功建立的回调方法
  websocket.onopen = function () {
    alert("WebSocket连接成功");
  }

  //连接发生错误的回调方法
  websocket.onerror = function () {
    alert("WebSocket连接发生错误");
  };
  
   //发送消息
  function sendMess(content) {
     var json ="{'username':'"+'${sessionScope.username }'+"', 'content':'"+content+"'}";
    websocket.send(json);
  }

  //接收到消息的回调方法
  websocket.onmessage = function (event) {
    var jsonString = event.data;    //接收到的信息存放在event.data中
    var data = JSON.parse(jsonString);  //将json字符串转换成js对象
    // 然后输出data
  }

   //连接关闭的回调方法
  websocket.onclose = function () {
    alert("WebSocket连接关闭");
  }

  //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  window.onbeforeunload = function () {
    closeWebSocket();
  }

  //关闭WebSocket连接
  function closeWebSocket() {
    websocket.close();
  }

二.服务器

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 {      //每进入一个用户,就新建一个ChatService对象
  
  private static int onlineCount = 0; //静态变量, 用来记录当前在线连接数
  private static Set<ChatService> webSocketSet = new HashSet<>();    //静态变量,用来存放在线用户
  private Session session;   //用于存储与该用户的会话,要通过它来给客户端发送数据

  /**
   * 连接建立成功调用的方法
   * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
   */
  @OnOpen
  public void onOpen(Session session){
    this.session = session;
    webSocketSet.add(this);   //加入set中
    addOnlineCount();      //在线数加1
    System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
  }
  
  /**
   * 连接关闭调用的方法
   */
  @OnClose
  public void onClose(){
    webSocketSet.remove(this); //从set中删除
    subOnlineCount();      //在线数减1
    System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
  }

  /**
   * 收到客户端消息后调用的方法
   * @param message 客户端发送过来的消息
   * @param session 可选的参数
   */
  @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());
    //群发消息
    for(ChatService item: webSocketSet){
      try {
        item.sendMessage(mess);
      } catch (IOException e) {
        e.printStackTrace();
        continue;
      }
    }
  }
  
  /**
   * 发生错误时调用
   * @param session
   * @param error
   */
  @OnError
  public void onError(Session session, Throwable error){
    System.out.println("发生错误");
    error.printStackTrace();
  }

  //以下为辅助函数
  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);    //将消息对象转换成json字符串
    this.session.getAsyncRemote().sendText(jsonInfo); //通过session异步地将信息发送到客户端上
  }

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++实现扫雷游戏示例讲解

    C++实现扫雷游戏示例讲解

    这篇文章主要介绍了C++实现扫雷游戏示例讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • SpringBoot读取properties文件配置项过程解析

    SpringBoot读取properties文件配置项过程解析

    这篇文章主要介绍了SpringBoot读取properties文件配置项过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 基于Freemarker和xml实现Java导出word

    基于Freemarker和xml实现Java导出word

    这篇文章主要介绍了基于Freemarker和xml实现Java导出word,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • JavaSE实现文件压缩与解压缩的技巧分享

    JavaSE实现文件压缩与解压缩的技巧分享

    我们在日常实际开发中,对于文件压缩和解压缩场景,是非常常见的操作,本文详细介绍JavaSE中文件压缩和解压缩的实现方法,包括源代码解析、应用场景案例、优缺点分析、案例演示、文末总结等等,请同学们耐心阅读
    2024-03-03
  • Java Maven依赖传递,可选依赖,排除依赖详解

    Java Maven依赖传递,可选依赖,排除依赖详解

    这篇文章主要介绍了Java Maven依赖传递,可选依赖,排除依赖详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • java中list使用时需避免的场景总结

    java中list使用时需避免的场景总结

    众所周知,Java为开发者提供了多种集合类的实现,其中几乎所有业务代码都需要用到List,但List的错误使用也会导致诸多问题,所以本文我们就来看一看几个错误使用List的场景吧
    2023-10-10
  • Spring boot整合Mybatis-plus过程解析

    Spring boot整合Mybatis-plus过程解析

    这篇文章主要介绍了Spring boot整合Mybatis-plus过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 解决ObjectMapper序列换Map时候的坑

    解决ObjectMapper序列换Map时候的坑

    这篇文章主要介绍了解决ObjectMapper序列换Map时候的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • java模拟多线程http请求代码分享

    java模拟多线程http请求代码分享

    本篇文章给大家分享了java模拟多线程http请求的相关实例代码,对此有需要的可以跟着测试下。
    2018-05-05
  • spring task @Scheduled注解各参数的用法

    spring task @Scheduled注解各参数的用法

    这篇文章主要介绍了spring task @Scheduled注解各参数的用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10

最新评论