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;
    }
  }
});

 

目录
相关文章
|
4月前
|
Java 应用服务中间件 Windows
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
|
1月前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
51 2
|
2月前
|
安全 Java 数据安全/隐私保护
如何配置 Java 安全管理器来避免访问控制异常
配置Java安全管理器以防止访问控制异常,需在启动JVM时通过 `-Djava.security.manager` 参数启用,并设置安全策略文件,定义权限规则,限制代码执行操作,确保应用安全。
151 1
|
2月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
158 1
|
2月前
|
消息中间件 分布式计算 Java
大数据-73 Kafka 高级特性 稳定性-事务 相关配置 事务操作Java 幂等性 仅一次发送
大数据-73 Kafka 高级特性 稳定性-事务 相关配置 事务操作Java 幂等性 仅一次发送
37 2
|
2月前
|
分布式计算 资源调度 Hadoop
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
88 4
|
2月前
|
Java Shell Maven
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
128 4
|
2月前
|
消息中间件 Java 大数据
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
76 2
|
3月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
2月前
|
负载均衡 算法 Java
java中nginx负载均衡配置
java中nginx负载均衡配置
59 0
下一篇
DataWorks