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;

}

}

});

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容