java WebSocket 即时通讯配置使用说明

简介: java WebSocket 即时通讯配置使用说明

1. 后台 启动类,执行main方法启动

package com.fh;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Date;
import net.sf.json.JSONObject;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
/**
 * @author FH
 * from fhadmin.cn
 * 2021-5-16
 */
public class ChatServer extends WebSocketServer{
  public ChatServer(int port) throws UnknownHostException {
    super(new InetSocketAddress(port));
  }
  public ChatServer(InetSocketAddress address) {
    super(address);
  }
  /**
   * 触发连接事件
   */
  @Override
  public void onOpen( WebSocket conn, ClientHandshake handshake ) {
    //this.sendToAll( "new connection: " + handshake.getResourceDescriptor() );
    //System.out.println( conn.getRemoteSocketAddress().getAddress().getHostAddress());
  }
  /**
   * 触发关闭事件
   */
  @Override
  public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
    userLeave(conn);
  }
  /**
   * 客户端发送消息到服务器时触发事件
   */
  @Override
  public void onMessage(WebSocket conn, String message){
    message = message.toString();
    if(null != message && message.startsWith("FHadmin313596790")){
      this.userjoin(message.replaceFirst("FHadmin313596790", ""),conn);
    }if(null != message && message.startsWith("LeaveFHadmin313596790")){
      this.userLeave(conn);
    }if(null != message && message.contains("fhadmin886")){
      String toUser = message.substring(message.indexOf("fhadmin886")+10, message.indexOf("fhfhadmin888"));
      message = message.substring(0, message.indexOf("fhadmin886")) +"[私信]  "+ message.substring(message.indexOf("fhfhadmin888")+12, message.length());
      ChatServerPool.sendMessageToUser(ChatServerPool.getWebSocketByUser(toUser),message);//向所某用户发送消息
      ChatServerPool.sendMessageToUser(conn, message);//同时向本人发送消息
    }else{
      ChatServerPool.sendMessage(message.toString());//向所有在线用户发送消息
    }
  }
  public void onFragment( WebSocket conn, Framedata fragment ) {
  }
  /**
   * 触发异常事件
   */
  @Override
  public void onError( WebSocket conn, Exception ex ) {
    ex.printStackTrace();
    if( conn != null ) {
      //some errors like port binding failed may not be assignable to a specific websocket
    }
  }
  /**
   * 用户加入处理
   * @param user
   */
  public void userjoin(String user, WebSocket conn){
    JSONObject result = new JSONObject();
    result.element("type", "user_join");
    result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
    ChatServerPool.sendMessage(result.toString());        //把当前用户加入到所有在线用户列表中
    String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"上线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
    ChatServerPool.sendMessage(joinMsg);            //向所有在线用户推送当前用户上线的消息
    result = new JSONObject();
    result.element("type", "get_online_user");
    ChatServerPool.addUser(user,conn);              //向连接池添加当前的连接对象
    result.element("list", ChatServerPool.getOnlineUser());
    ChatServerPool.sendMessageToUser(conn, result.toString());  //向当前连接发送当前在线用户的列表
  }
  /**
   * 用户下线处理
   * @param user
   */
  public void userLeave(WebSocket conn){
    String user = ChatServerPool.getUserByKey(conn);
    boolean b = ChatServerPool.removeUser(conn);        //在连接池中移除连接
    if(b){
      JSONObject result = new JSONObject();
      result.element("type", "user_leave");
      result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
      ChatServerPool.sendMessage(result.toString());      //把当前用户从所有在线用户列表中删除
      String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"下线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
      ChatServerPool.sendMessage(joinMsg);          //向在线用户发送当前用户退出的消息
    }
  }
  public static void main( String[] args ) throws InterruptedException , IOException {
    WebSocketImpl.DEBUG = false;
    int port = 8887; //端口
    ChatServer s = new ChatServer(port);
    s.start();
    //System.out.println( "服务器的端口" + s.getPort() );
  }
}

2.ChatServerPool.java

package com.fh;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.java_websocket.WebSocket;
/**
 * @author FH
 * from fhadmin.cn
 * 2021-5-16
 */
public class ChatServerPool {
  /*保存连接的MAP容器*/
  private static final Map<WebSocket,String> userconnections = new HashMap<WebSocket,String>();
  /**
   * 获取用户名
   * @param session
   */
  public static String getUserByKey(WebSocket conn){
    return userconnections.get(conn);
  }
  /**
   * 获取WebSocket
   * @param user
   */
  public static WebSocket getWebSocketByUser(String user){
    Set<WebSocket> keySet = userconnections.keySet();
    synchronized (keySet) {
      for (WebSocket conn : keySet) {
        String cuser = userconnections.get(conn);
        if(cuser.equals(user)){
          return conn;
        }
      }
    }
    return null;
  }
  /**
   * 向连接池中添加连接
   * @param inbound
   */
  public static void addUser(String user, WebSocket conn){
    userconnections.put(conn,user); //添加连接
  }
  /**
   * 获取所有的在线用户
   * @return
   */
  public static Collection<String> getOnlineUser(){
    List<String> setUsers = new ArrayList<String>();
    Collection<String> setUser = userconnections.values();
    for(String u:setUser){
      setUsers.add("<a onclick=\"toUserMsg('"+u+"');\">"+u+"</a>");
    }
    return setUsers;
  }
  /**
   * 移除连接池中的连接
   * @param inbound
   */
  public static boolean removeUser(WebSocket conn){
    if(userconnections.containsKey(conn)){
      userconnections.remove(conn); //移除连接
      return true;
    }else{
      return false;
    }
  }
  /**
   * 向特定的用户发送数据
   * @param user
   * @param message
   */
  public static void sendMessageToUser(WebSocket conn,String message){
    if(null != conn && null != userconnections.get(conn)){
      conn.send(message);
    }
  }
  /**
   * 向所有的用户发送消息
   * @param message
   */
  public static void sendMessage(String message){
    Set<WebSocket> keySet = userconnections.keySet();
    synchronized (keySet) {
      for (WebSocket conn : keySet) {
        String user = userconnections.get(conn);
        if(user != null){
          conn.send(message);
        }
      }
    }
  }
}

3.前端

var websocket;
var isCreatw = false;
var title="";
var win;
var input;
var isQj = true;
var toUser="";
function toUserMsg(toU){
  if((!isQj && toUser == toU) || toU == user){
    win.setTitle(title + "&nbsp;&nbsp;(已连接)   【现在全局对话】");
    isQj = true;
    toUser = "";
  }else{
    win.setTitle(title + "&nbsp;&nbsp;(已连接)   【现在单独与"+toU+"对话】");
    isQj = false;
    toUser = toU;
  }
}
 function creatw() {
      if(isCreatw){
        alert("已经启动");
        return;
      }else{
        isCreatw = true;
      }
      //创建用户输入框
      input = Ext.create('Ext.form.field.HtmlEditor', {
            region : 'south',
            height : 120,
            enableFont : false,
            enableSourceEdit : false,
            enableAlignments : false,
            listeners : {
              initialize : function() {
                Ext.EventManager.on(me.input.getDoc(), {
                      keyup : function(e) {
                        if (e.ctrlKey === true
                            && e.keyCode == 13) {
                          e.preventDefault();
                          e.stopPropagation();
                          send();
                        }
                      }
                    });
              }
            }
          });
      //创建消息展示容器
      var output = Ext.create('MessageContainer', {
            region : 'center'
          });
      var dialog = Ext.create('Ext.panel.Panel', {
            region : 'center',
            layout : 'border',
            items : [input, output],
            buttons : [{
                  text : '发送',
                  handler : send
                }]
          });
      //初始话WebSocket
      function initWebSocket() {
        if (window.WebSocket) {
          websocket = new WebSocket(encodeURI('ws://127.0.0.1:8887'));
          websocket.onopen = function() {
            //连接成功
            win.setTitle(title + '&nbsp;&nbsp;(已连接)   【现在全局对话】');
            websocket.send('FHadmin313596790'+user);
          }
          websocket.onerror = function() {
            //连接失败
            win.setTitle(title + '&nbsp;&nbsp;(连接发生错误)');
          }
          websocket.onclose = function() {
            //连接断开
            win.setTitle(title + '&nbsp;&nbsp;(已经断开连接)');
          }
          //消息接收
          websocket.onmessage = function(message) {
            var message = JSON.parse(message.data);
            //接收用户发送的消息
            if (message.type == 'message') {
              output.receive(message);
            } else if (message.type == 'get_online_user') {
              //获取在线用户列表
              var root = onlineUser.getRootNode();
              Ext.each(message.list,function(user){
                var node = root.createNode({
                  id : user,
                  text : user,
                  iconCls : 'user',
                  leaf : true
                });
                root.appendChild(node);
              });
            } else if (message.type == 'user_join') {
              //用户上线
                var root = onlineUser.getRootNode();
                var user = message.user;
                var node = root.createNode({
                  id : user,
                  text : user,
                  iconCls : 'user',
                  leaf : true
                });
                root.appendChild(node);
            } else if (message.type == 'user_leave') {
                //用户下线
                var root = onlineUser.getRootNode();
                var user = message.user;
                var node = root.findChild('id',user);
                root.removeChild(node);
            }
          }
        }
      };
      //在线用户树
      var onlineUser = Ext.create('Ext.tree.Panel', {
            title : '在线用户',
            rootVisible : false,
            region : 'east',
            width : 150,
            lines : false,
            useArrows : true,
            autoScroll : true,
            split : true,
            iconCls : 'user-online',
            store : Ext.create('Ext.data.TreeStore', {
                  root : {
                    text : '在线用户',
                    expanded : true,
                    children : []
                  }
                })
          });
      title = '欢迎您:' + user;
      //展示窗口
      win = Ext.create('Ext.window.Window', {
            title : title + '&nbsp;&nbsp;(未连接)',
            layout : 'border',
            iconCls : 'user-win',
            minWidth : 650,
            minHeight : 460,
            width : 650,
            animateTarget : 'websocket_button',
            height : 460,
            items : [dialog,onlineUser],
            border : false,
            listeners : {
              render : function() {
                initWebSocket();
              }
            }
          });
      win.show();
      win.on("close",function(){
        websocket.send('LeaveFHadmin313596790');
        isCreatw = false;
       });
      //发送消息
      function send() {
        var content = input.getValue();
        if(toUser != ""){content = "fhadmin886"+toUser+"fhfhadmin888" + content;}
        var message = {};
        if (websocket != null) {
          if (input.getValue()) {
            Ext.apply(message, {
                  from : user,
                  content : content,
                  timestamp : new Date().getTime(),
                  type : 'message'
                });
            websocket.send(JSON.stringify(message));
            //output.receive(message);
            input.setValue('');
          }
        } else {
          Ext.Msg.alert('提示', '您已经掉线,无法发送消息!');
        }
      }
};
//用于展示用户的聊天信息
Ext.define('MessageContainer', {
  extend : 'Ext.view.View',
  trackOver : true,
  multiSelect : false,
  itemCls : 'l-im-message',
  itemSelector : 'div.l-im-message',
  overItemCls : 'l-im-message-over',
  selectedItemCls : 'l-im-message-selected',
  style : {
    overflow : 'auto',
    backgroundColor : '#fff'
  },
  tpl : [
      '<div class="l-im-message-warn">欢迎使用FH Admin 即时通讯系统。</div>',
      '<tpl for=".">',
      '<div class="l-im-message">',
      '<div class="l-im-message-header l-im-message-header-{source}">{from}  {timestamp}</div>',
      '<div class="l-im-message-body">{content}</div>', '</div>',
      '</tpl>'],
  messages : [],
  initComponent : function() {
    var me = this;
    me.messageModel = Ext.define('Leetop.im.MessageModel', {
          extend : 'Ext.data.Model',
          fields : ['from', 'timestamp', 'content', 'source']
        });
    me.store = Ext.create('Ext.data.Store', {
          model : 'Leetop.im.MessageModel',
          data : me.messages
        });
    me.callParent();
  },
  //将服务器推送的信息展示到页面中
  receive : function(message) {
    var me = this;
    message['timestamp'] = Ext.Date.format(new Date(message['timestamp']),
        'H:i:s');
    if(message.from == user){
      message.source = 'self';
    }else{
      message.source = 'remote';
    }
    me.store.add(message);
    if (me.el.dom) {
      me.el.dom.scrollTop = me.el.dom.scrollHeight;
    }
  }
});

 

目录
相关文章
|
2天前
|
监控 JavaScript 前端开发
《理解 WebSocket:Java Web 开发的实时通信技术》
【4月更文挑战第4天】WebSocket是Java Web实时通信的关键技术,提供双向持久连接,实现低延迟、高效率的实时交互。适用于聊天应用、在线游戏、数据监控和即时通知。开发涉及服务器端实现、客户端连接及数据协议定义,注意安全、错误处理、性能和兼容性。随着实时应用需求增加,WebSocket在Java Web开发中的地位将更加重要。
|
2天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——TestStu.java
hibernate正向生成数据库表以及配置——TestStu.java
20 1
|
2天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——Teacher.java
hibernate正向生成数据库表以及配置——Teacher.java
14 0
|
2天前
|
JSON 数据格式
【虚幻引擎】DTWebSocketServer 蓝图创建WebSocket服务器插件使用说明
该插件用于创建和管理WebSocket服务器,支持通过蓝图创建服务器、监听端口并接收响应。主要功能包括:创建服务器、绑定各种回调函数(用户连接、断开、发送消息时触发)、关闭服务器、获取所有用户、获取用户数据、向用户发送消息及主动关闭用户连接。示例和下载链接在原文中提供。
37 2
|
2天前
|
Java
Java配置环境
Java配置环境
22 0
Java配置环境
|
1天前
|
Java 程序员 Windows
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
|
2天前
|
IDE Java 应用服务中间件
JDK1.6.0+Tomcat6.0的安装配置(配置JAVA环境)
JDK1.6.0+Tomcat6.0的安装配置(配置JAVA环境)
18 1
|
2天前
|
Oracle Java 关系型数据库
windows 下 win11 JDK17安装与环境变量的配置(配置简单详细,包含IJ中java文件如何使用命令运行)
本文介绍了Windows 11中安装JDK 17的步骤,包括从官方网站下载JDK、配置环境变量以及验证安装是否成功。首先,下载JDK 17的安装文件,如果没有Oracle账户,可以直接解压缩文件到指定目录。接着,配置系统环境变量,新建`JAVA_HOME`变量指向JDK安装路径,并在`Path`变量中添加。然后,通过命令行(cmd)验证安装,分别输入`java -version`和`javac -version`检查版本信息。最后,作者分享了如何在任意位置运行Java代码,包括在IntelliJ IDEA(IJ)中创建的Java文件,只需去掉包声明,就可以通过命令行直接运行。
|
2天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
21 1
|
2天前
|
Java Windows
java——安装JDK及配置解决常见问题
java——安装JDK及配置解决常见问题