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

朱雀 2022-09-05 12:58 351阅读 0赞
  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;

  1. /**
  2. * @author FH
  3. * from fhadmin.cn
  4. * 2021-5-16
  5. */
  6. public class ChatServer extends WebSocketServer{
  7. public ChatServer(int port) throws UnknownHostException {
  8. super(new InetSocketAddress(port));
  9. }
  10. public ChatServer(InetSocketAddress address) {
  11. super(address);
  12. }
  13. /**
  14. * 触发连接事件
  15. */
  16. @Override
  17. public void onOpen( WebSocket conn, ClientHandshake handshake ) {
  18. //this.sendToAll( "new connection: " + handshake.getResourceDescriptor() );
  19. //System.out.println( conn.getRemoteSocketAddress().getAddress().getHostAddress());
  20. }
  21. /**
  22. * 触发关闭事件
  23. */
  24. @Override
  25. public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
  26. userLeave(conn);
  27. }
  28. /**
  29. * 客户端发送消息到服务器时触发事件
  30. */
  31. @Override
  32. public void onMessage(WebSocket conn, String message){
  33. message = message.toString();
  34. if(null != message && message.startsWith("FHadmin313596790")){
  35. this.userjoin(message.replaceFirst("FHadmin313596790", ""),conn);
  36. }if(null != message && message.startsWith("LeaveFHadmin313596790")){
  37. this.userLeave(conn);
  38. }if(null != message && message.contains("fhadmin886")){
  39. String toUser = message.substring(message.indexOf("fhadmin886")+10, message.indexOf("fhfhadmin888"));
  40. message = message.substring(0, message.indexOf("fhadmin886")) +"[私信] "+ message.substring(message.indexOf("fhfhadmin888")+12, message.length());
  41. ChatServerPool.sendMessageToUser(ChatServerPool.getWebSocketByUser(toUser),message);//向所某用户发送消息
  42. ChatServerPool.sendMessageToUser(conn, message);//同时向本人发送消息
  43. }else{
  44. ChatServerPool.sendMessage(message.toString());//向所有在线用户发送消息
  45. }
  46. }
  47. public void onFragment( WebSocket conn, Framedata fragment ) {
  48. }
  49. /**
  50. * 触发异常事件
  51. */
  52. @Override
  53. public void onError( WebSocket conn, Exception ex ) {
  54. ex.printStackTrace();
  55. if( conn != null ) {
  56. //some errors like port binding failed may not be assignable to a specific websocket
  57. }
  58. }
  59. /**
  60. * 用户加入处理
  61. * @param user
  62. */
  63. public void userjoin(String user, WebSocket conn){
  64. JSONObject result = new JSONObject();
  65. result.element("type", "user_join");
  66. result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
  67. ChatServerPool.sendMessage(result.toString()); //把当前用户加入到所有在线用户列表中
  68. String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"上线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
  69. ChatServerPool.sendMessage(joinMsg); //向所有在线用户推送当前用户上线的消息
  70. result = new JSONObject();
  71. result.element("type", "get_online_user");
  72. ChatServerPool.addUser(user,conn); //向连接池添加当前的连接对象
  73. result.element("list", ChatServerPool.getOnlineUser());
  74. ChatServerPool.sendMessageToUser(conn, result.toString()); //向当前连接发送当前在线用户的列表
  75. }
  76. /**
  77. * 用户下线处理
  78. * @param user
  79. */
  80. public void userLeave(WebSocket conn){
  81. String user = ChatServerPool.getUserByKey(conn);
  82. boolean b = ChatServerPool.removeUser(conn); //在连接池中移除连接
  83. if(b){
  84. JSONObject result = new JSONObject();
  85. result.element("type", "user_leave");
  86. result.element("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
  87. ChatServerPool.sendMessage(result.toString()); //把当前用户从所有在线用户列表中删除
  88. String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"下线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
  89. ChatServerPool.sendMessage(joinMsg); //向在线用户发送当前用户退出的消息
  90. }
  91. }
  92. public static void main( String[] args ) throws InterruptedException , IOException {
  93. WebSocketImpl.DEBUG = false;
  94. int port = 8887; //端口
  95. ChatServer s = new ChatServer(port);
  96. s.start();
  97. //System.out.println( "服务器的端口" + s.getPort() );
  98. }
  99. }

2.ChatServerPool.java

  1. package com.fh;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8. import org.java_websocket.WebSocket;
  9. /**
  10. * @author FH
  11. * from fhadmin.cn
  12. * 2021-5-16
  13. */
  14. public class ChatServerPool {
  15. /*保存连接的MAP容器*/
  16. private static final Map<WebSocket,String> userconnections = new HashMap<WebSocket,String>();
  17. /**
  18. * 获取用户名
  19. * @param session
  20. */
  21. public static String getUserByKey(WebSocket conn){
  22. return userconnections.get(conn);
  23. }
  24. /**
  25. * 获取WebSocket
  26. * @param user
  27. */
  28. public static WebSocket getWebSocketByUser(String user){
  29. Set<WebSocket> keySet = userconnections.keySet();
  30. synchronized (keySet) {
  31. for (WebSocket conn : keySet) {
  32. String cuser = userconnections.get(conn);
  33. if(cuser.equals(user)){
  34. return conn;
  35. }
  36. }
  37. }
  38. return null;
  39. }
  40. /**
  41. * 向连接池中添加连接
  42. * @param inbound
  43. */
  44. public static void addUser(String user, WebSocket conn){
  45. userconnections.put(conn,user); //添加连接
  46. }
  47. /**
  48. * 获取所有的在线用户
  49. * @return
  50. */
  51. public static Collection<String> getOnlineUser(){
  52. List<String> setUsers = new ArrayList<String>();
  53. Collection<String> setUser = userconnections.values();
  54. for(String u:setUser){
  55. setUsers.add("<a onclick=\"toUserMsg('"+u+"');\">"+u+"</a>");
  56. }
  57. return setUsers;
  58. }
  59. /**
  60. * 移除连接池中的连接
  61. * @param inbound
  62. */
  63. public static boolean removeUser(WebSocket conn){
  64. if(userconnections.containsKey(conn)){
  65. userconnections.remove(conn); //移除连接
  66. return true;
  67. }else{
  68. return false;
  69. }
  70. }
  71. /**
  72. * 向特定的用户发送数据
  73. * @param user
  74. * @param message
  75. */
  76. public static void sendMessageToUser(WebSocket conn,String message){
  77. if(null != conn && null != userconnections.get(conn)){
  78. conn.send(message);
  79. }
  80. }
  81. /**
  82. * 向所有的用户发送消息
  83. * @param message
  84. */
  85. public static void sendMessage(String message){
  86. Set<WebSocket> keySet = userconnections.keySet();
  87. synchronized (keySet) {
  88. for (WebSocket conn : keySet) {
  89. String user = userconnections.get(conn);
  90. if(user != null){
  91. conn.send(message);
  92. }
  93. }
  94. }
  95. }
  96. }

3.前端

  1. var websocket;
  2. var isCreatw = false;
  3. var title="";
  4. var win;
  5. var input;
  6. var isQj = true;
  7. var toUser="";
  8. function toUserMsg(toU){
  9. if((!isQj && toUser == toU) || toU == user){
  10. win.setTitle(title + " (已连接) 【现在全局对话】");
  11. isQj = true;
  12. toUser = "";
  13. }else{
  14. win.setTitle(title + " (已连接) 【现在单独与"+toU+"对话】");
  15. isQj = false;
  16. toUser = toU;
  17. }
  18. }
  19. function creatw() {
  20. if(isCreatw){
  21. alert("已经启动");
  22. return;
  23. }else{
  24. isCreatw = true;
  25. }
  26. //创建用户输入框
  27. input = Ext.create('Ext.form.field.HtmlEditor', {
  28. region : 'south',
  29. height : 120,
  30. enableFont : false,
  31. enableSourceEdit : false,
  32. enableAlignments : false,
  33. listeners : {
  34. initialize : function() {
  35. Ext.EventManager.on(me.input.getDoc(), {
  36. keyup : function(e) {
  37. if (e.ctrlKey === true
  38. && e.keyCode == 13) {
  39. e.preventDefault();
  40. e.stopPropagation();
  41. send();
  42. }
  43. }
  44. });
  45. }
  46. }
  47. });
  48. //创建消息展示容器
  49. var output = Ext.create('MessageContainer', {
  50. region : 'center'
  51. });
  52. var dialog = Ext.create('Ext.panel.Panel', {
  53. region : 'center',
  54. layout : 'border',
  55. items : [input, output],
  56. buttons : [{
  57. text : '发送',
  58. handler : send
  59. }]
  60. });
  61. //初始话WebSocket
  62. function initWebSocket() {
  63. if (window.WebSocket) {
  64. websocket = new WebSocket(encodeURI('ws://127.0.0.1:8887'));
  65. websocket.onopen = function() {
  66. //连接成功
  67. win.setTitle(title + ' (已连接) 【现在全局对话】');
  68. websocket.send('FHadmin313596790'+user);
  69. }
  70. websocket.onerror = function() {
  71. //连接失败
  72. win.setTitle(title + ' (连接发生错误)');
  73. }
  74. websocket.onclose = function() {
  75. //连接断开
  76. win.setTitle(title + ' (已经断开连接)');
  77. }
  78. //消息接收
  79. websocket.onmessage = function(message) {
  80. var message = JSON.parse(message.data);
  81. //接收用户发送的消息
  82. if (message.type == 'message') {
  83. output.receive(message);
  84. } else if (message.type == 'get_online_user') {
  85. //获取在线用户列表
  86. var root = onlineUser.getRootNode();
  87. Ext.each(message.list,function(user){
  88. var node = root.createNode({
  89. id : user,
  90. text : user,
  91. iconCls : 'user',
  92. leaf : true
  93. });
  94. root.appendChild(node);
  95. });
  96. } else if (message.type == 'user_join') {
  97. //用户上线
  98. var root = onlineUser.getRootNode();
  99. var user = message.user;
  100. var node = root.createNode({
  101. id : user,
  102. text : user,
  103. iconCls : 'user',
  104. leaf : true
  105. });
  106. root.appendChild(node);
  107. } else if (message.type == 'user_leave') {
  108. //用户下线
  109. var root = onlineUser.getRootNode();
  110. var user = message.user;
  111. var node = root.findChild('id',user);
  112. root.removeChild(node);
  113. }
  114. }
  115. }
  116. };
  117. //在线用户树
  118. var onlineUser = Ext.create('Ext.tree.Panel', {
  119. title : '在线用户',
  120. rootVisible : false,
  121. region : 'east',
  122. width : 150,
  123. lines : false,
  124. useArrows : true,
  125. autoScroll : true,
  126. split : true,
  127. iconCls : 'user-online',
  128. store : Ext.create('Ext.data.TreeStore', {
  129. root : {
  130. text : '在线用户',
  131. expanded : true,
  132. children : []
  133. }
  134. })
  135. });
  136. title = '欢迎您:' + user;
  137. //展示窗口
  138. win = Ext.create('Ext.window.Window', {
  139. title : title + ' (未连接)',
  140. layout : 'border',
  141. iconCls : 'user-win',
  142. minWidth : 650,
  143. minHeight : 460,
  144. width : 650,
  145. animateTarget : 'websocket_button',
  146. height : 460,
  147. items : [dialog,onlineUser],
  148. border : false,
  149. listeners : {
  150. render : function() {
  151. initWebSocket();
  152. }
  153. }
  154. });
  155. win.show();
  156. win.on("close",function(){
  157. websocket.send('LeaveFHadmin313596790');
  158. isCreatw = false;
  159. });
  160. //发送消息
  161. function send() {
  162. var content = input.getValue();
  163. if(toUser != ""){content = "fhadmin886"+toUser+"fhfhadmin888" + content;}
  164. var message = {};
  165. if (websocket != null) {
  166. if (input.getValue()) {
  167. Ext.apply(message, {
  168. from : user,
  169. content : content,
  170. timestamp : new Date().getTime(),
  171. type : 'message'
  172. });
  173. websocket.send(JSON.stringify(message));
  174. //output.receive(message);
  175. input.setValue('');
  176. }
  177. } else {
  178. Ext.Msg.alert('提示', '您已经掉线,无法发送消息!');
  179. }
  180. }
  181. };
  182. //用于展示用户的聊天信息
  183. Ext.define('MessageContainer', {
  184. extend : 'Ext.view.View',
  185. trackOver : true,
  186. multiSelect : false,
  187. itemCls : 'l-im-message',
  188. itemSelector : 'div.l-im-message',
  189. overItemCls : 'l-im-message-over',
  190. selectedItemCls : 'l-im-message-selected',
  191. style : {
  192. overflow : 'auto',
  193. backgroundColor : '#fff'
  194. },
  195. tpl : [
  196. '<div class="l-im-message-warn">​欢迎使用FH Admin 即时通讯系统。</div>',
  197. '<tpl for=".">',
  198. '<div class="l-im-message">',
  199. '<div class="l-im-message-header l-im-message-header-{source}">{from} {timestamp}</div>',
  200. '<div class="l-im-message-body">{content}</div>', '</div>',
  201. '</tpl>'],
  202. messages : [],
  203. initComponent : function() {
  204. var me = this;
  205. me.messageModel = Ext.define('Leetop.im.MessageModel', {
  206. extend : 'Ext.data.Model',
  207. fields : ['from', 'timestamp', 'content', 'source']
  208. });
  209. me.store = Ext.create('Ext.data.Store', {
  210. model : 'Leetop.im.MessageModel',
  211. data : me.messages
  212. });
  213. me.callParent();
  214. },
  215. //将服务器推送的信息展示到页面中
  216. receive : function(message) {
  217. var me = this;
  218. message['timestamp'] = Ext.Date.format(new Date(message['timestamp']),
  219. 'H:i:s');
  220. if(message.from == user){
  221. message.source = 'self';
  222. }else{
  223. message.source = 'remote';
  224. }
  225. me.store.add(message);
  226. if (me.el.dom) {
  227. me.el.dom.scrollTop = me.el.dom.scrollHeight;
  228. }
  229. }
  230. });

发表评论

表情:
评论列表 (有 0 条评论,351人围观)

还没有评论,来说两句吧...

相关阅读