实现流程:

  1.浏览器连接服务器时保存所有用户id以及对应的唯一session(session用户用户消息推送)。

    1.1:判断登录用户是否有离线消息(个人消息以及群消息),有则将离线消息进行推送给登录用户。

  2.前端layim监听消息发送,监听到通过websocket send方法将消息对象发送至服务器

  3.服务器接收到消息,通多消息对象获取接收者id,通过接收者id获取唯一session。

    3.1: 个人聊天可先判断用户是否在线,如果在线可直接通过接受者id进行消息推送,如果不在线就保存消息,待接收者上线时将此消息推送给接受者。

    3.2: 群消息通过群id获取所有群成员,循环如果在线则发送消息,不在线保存消息。待接收者上线时将消息推送给消息接收者。

  4.服务器通过session进行消息推送

java

package com.healta.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import com.healta.chat.vo.User;
import com.jfinal.plugin.activerecord.Record; //与js代码 new ReconnectingWebSocket("ws://IP地址:端口号/项目根路径/websocket配置的路径/" + 传的参数,可多个)对应
@ServerEndpoint("/websocket/{userId}")
public class WebSocketController { public static Map<Integer, User> userMap = new HashMap<>();//保存在线用户 public static List<Integer> onLineUserIdList = new ArrayList<>();//保存在线的用户id
public static User user; /**
* 浏览器连服务器时触发此方法
* @param session
* @param userId
*/
@OnOpen
public void onOpen(Session session, @PathParam("userId") Integer userId) {
/**
* 判断当前连接用户是否在线
*/
if(!checkOnLineState){//用户上线保存用户唯一session以及保存用户id,可通过用户id获取session
user = new User();
user.setUserSession(session);
user.setUserOnLineType(true);
userMap.put(userId, user);
onLineUserIdList.add(userId);
} //往下可根据不同的需求写相应的逻辑代码,比如离线消息就可以在用户连接服务器时去进行消息推送。或者用户上线提醒。 } /**
* 连接关闭会触发此事件
* @param session
* @param userId
*/
@OnClose
public void onClose(Session session, @PathParam("userId") Integer userId) {
          //用户下线需要将对于的在线用户进行调整。
onLineUserIdList.remove(userId);
userMap.remove(userId);
//用户下线可以给前端推送一个下线消息,前端接收把好友置灰
} /**
* 服务器收到消息时触发此方法
* @param requestJson
* @param session
* @param userId
*/
@OnMessage
public void onMessage(String requestJson, Session session, @PathParam("userId") Integer userId) { //此处通过requestJson消息对象可获取收信人id或者群id
JSONObject messageObject = JSONObject.parseObject(requestJson);
String jsonCollectUserId = messageObject.getString("collectUserId");//消息接收者可以是群id也可以是用户id
String jsonContent = messageObject.getString("content");//消息内容 try {
//通过收件人id获取连接session进行消息推送
userMap.get(收信人id或者群id).getUserSession().getBasicRemote().sendText("消息字符串,用layim的话需要和layim的消息接收类型一致。");
} catch (IOException e) {
e.printStackTrace();
} }
}

  

js

<script>
layui.use('layim', function(layim){
var copyLayim = layim;
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new ReconnectingWebSocket("ws://IP地址:端口号/项目根路径/websocket配置的路径/" + 传的参数,可多个);
} else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function() {};
//连接成功建立的回调方法
websocket.onopen = function() {}
//接收到消息的回调方法
websocket.onmessage = function(event) {
var data = event.data;//服务器返回的消息,前端页面可以根据不同的消息做不同的操作。 }
//连接关闭的回调方法
websocket.onclose = function() {
// setMessageInnerHTML("WebSocket连接关闭");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
// document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send(msg) {
websocket.send(msg);
} layim.config({
brief: false, //是否简约模式(如果true则不显示主面板)
init: {
url: '基本数据获取接口(格式layui官网有提供)'
,data: {'userId': userId}
},
members: {
url: '返回群成员接口',
},
uploadImage: {
url: '图皮上传接口'
} ,
chatLog: '跳转至聊天界面url' ,
}); //layim消息发送监听器
layim.on('sendMessage', function(res) {
var mine = res.mine; //包含我发送的消息及我的信息
var to = res.to; //对方的信息
var msg = {
'collectUserId': to.id,
'content': mine.content
}
send(JSON.stringify(msg));
}); //监听修改签名
layim.on('sign', function(value){
此处可以ajax修改签名
});
});
</script>

websocket 加layim实现在线聊天系统的更多相关文章

  1. python全栈开发day115、116-websocket、websocket原理、websocket加解密、简单问答机器人实现

    1.websocket 1.websocket 与轮询 轮询: 不断向服务器发起询问,服务器还不断的回复 浪费带宽,浪费前后端资源 保证数据的实时性 长轮询: 1.客户端向服务器发起消息,服务端轮询, ...

  2. ArcGIS Javascript API 加载高德在线地图扩展

    利用ArcGIS JavaScript API加载高德在线地图的扩展 /** * Created by WanderGIS on 2015/7/15. */ define(["dojo/_b ...

  3. leaflet-webpack 入门开发系列二加载不同在线地图切换显示(附源码下载)

    前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...

  4. Java 并发专题 :FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等

    继续并发专题~ FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞. 由于:Fu ...

  5. WebSocket实现简单的在线聊天

    SuperWebSocket在WebService中的应用 最开始使用是寄托在IIS中,发布之后测试时半个小时就会断开,所以改为WindowsService 1. 新建Windows服务项目[Test ...

  6. 使用WebSocket实现简单的在线聊天室

    前言:我自已在网上找好了好多 WebSocket 制作 在线聊天室的案列,发现大佬们写得太高深了 我这种新手看不懂,所以就自已尝试写了一个在线简易聊天室 (我只用了js 可以用jq ) 话不多说,直接 ...

  7. 原生nodejs在线聊天系统

    前端自动化由来已久,最近为了编写自己的自动化工具,本人开始详细学习node,为了检验学习成果,决定编写一个类似于webqq的聊天系统.以下是该系统具有的模块. 登录模块(自动登录) 聊天模块(私聊,群 ...

  8. springboot+websocket实现简单的在线聊天功能

    效果如下: java实现逻辑: 1.引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId&g ...

  9. Linux网络编程(多人在线聊天系统)

    一.首先是服务器的建立 首先是一个信号终止程序,发信号ctrl+c终止程序,而是是初始化网络通信. 创建一个描述符负责绑定服务器和监听服务器接收客户端的消息. socket()->sockadd ...

随机推荐

  1. IE8 下背景图标不显示

    如图所示 : 微博微信前方各应有个图标,但是IE8下图标没有显示 css如下 .weibo_icon{background: url(../ieImages/weibo_icon.png)no-rep ...

  2. 禅道——Linux服务器部署禅道

    前言 2019年6月14日 22:01:24 看看时间我知道,我离猝死依然不远~ 禅道是什么 | 禅道是专业的研发项目管理软件 禅道的官网 | https://www.zentao.net/ 禅道开源 ...

  3. 正则表达式、Calendar类、SimpleDateFormat类、Date类、BigDecimal类、BigInteger类、System类、Random类、Math类(Java基础知识十四)

    1.正则表达式的概述和简单使用 * A:正则表达式(一个字符串,是规则)     * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. * B: ...

  4. Ext js框架模拟Windows桌面菜单管理模板

    一款超炫的后台,Ext模拟Windows桌面,Ext经典浅蓝风格,功能非常强大,包括最大化.最小化.状态栏.桌面图标等,不过需要非常懂Ext脚本的才可驾驭它.​ 1.图片 ​2. [代码][HTML] ...

  5. oracle:程序后台提示Io异常: The Network Adapter could not establish the connection)

    今天要用tomcat部署一个系统,windows环境下,oracle和程序在一台机器上. 在配置jndi时,直接写成 jdbc:oracle:thin:@127.0.0.1:1521:orcl.启动程 ...

  6. driver, module以及怎么看他们

    1. driver和module的区别 https://unix.stackexchange.com/questions/47208/what-is-the-difference-between-ke ...

  7. [angularJS]ng-hide|ng-show切换

    <div class="row ng-scope"> <div class="col-lg-12"> <h1 class=&quo ...

  8. bzoj2004公交线路——DP+矩阵加速递推

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 求方案数,想到DP: 因为两个站间距离<=p,所以每p个站中所有车一定都会停靠至 ...

  9. 一梦浮生2012 IOS高级进阶目录

    一梦浮生2012 精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能; 擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制 ...

  10. hdu5822 color

    首先考虑假如是树上的做法:考虑dp,f(i)表示对i的子树染色的方案数.用hash可以实现查询两棵子树是否相同.从而根据hash值排序分类,将相同的子树放在一类. (1)f(i)等于每一类的f(p)乘 ...