页面建立连接:
function websocket(){
if ("WebSocket" in window){//判断浏览器是否支持websocekt
//var host = "ws://localhost/websocketindex/<shiro:principal></shiro:principal>"//所要连接的地址Ip和端口
var socket = new WebSocket(host);
try {
socket.onopen = function()//打开socekt
{
console.log("WebSocket连接成功");
};
socket.onmessage = function(event)//连接socekt
{
console.log(event.data);
if(event.data=="1"){
console.log("数据更新啦");
socket.send("通知后台");
}
};
socket.onclose = function()//关闭socekt连接
{
console.log("WebSocket连接关闭");
socket.close();
};
socket.onerror = function(obj)//连接错误
{
console.log("Socket错误");
};
}
catch (ex) {
log(ex);
}
}
else{
alert("该浏览器不支持,请切换到 Internet Explorer 10(0)模式");
}
}
后台代码监听数据库变化,有变化时,向前台发送消息,前端根据返回的值进行相应的操作
int m = userDao.insert(user);//数据库插入操作
if(m>0) {
//当插入成功是,webSocket向浏览器也就是客户端发送消息
WebSocketServlet wss = new WebSocketServlet();
try {
wss.sendMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
onMessage方法
@OnMessage
public void onMessage(String msg,Session session) {
try {
sendMessage();
} catch (IOException e) {
e.printStackTrace();
}
}
sendMessage()方法
public void sendMessage() throws IOException{
//群发消息
for(WebSocketServlet item: webSocketSet){
//注意这里:当数据库数据更新时,后台向前端发送1,这样页面就可以根据这个返回的1,来进行刷新页面更新数据
item.session.getBasicRemote().sendText("1");
}
}
项目过程中遇到的问题及要注意点
死循环
因为项目数据量较大,数据更新时需要存入redis缓存,然后再进行页面展示
- 前端onMessage方法的作用
socket.onmessage = function(event)
{event.data==1}
用于监听后台websocket是否发送消息,这个发送消息不是说调用后台的onMessage方法,而是是否调用群发消息,如果群发消息,就会触发前端的onMessage事件,并且可以接收到服务器发送的这个数据 “1”,
//群发消息
for(WebSocketServlet item: webSocketSet){
//注意这里:当数据库数据更新时,后台向前端发送1,这样页面就可以根据这个返回的1,来进行刷新页面更新数据
item.session.getBasicRemote().sendText("1");
}
前端的**socket.send()**着个方法前端给后端发送消息,可以触发后端的onMessage方法
注意这里就会发生死循环前台一直接受到消息,触发onMessage事件,触发后调用socket.send()方法,这个socket.send()会触发后台的onMessage()方法,后台的onMessage(),调用的是sendMessage(),这个方法中的item.session.getBasicRemote().sendText(“1”);可以触发前端的onMessage事件,如此就进入死循环
修改前端代码和后台代码
function websocket(){
if ("WebSocket" in window){//判断浏览器是否支持websocekt
//var host = "ws://localhost/websocketindex/<shiro:principal></shiro:principal>"//所要连接的地址Ip和端口
var socket = new WebSocket(host);
try {
socket.onopen = function()//打开socekt
{
console.log("WebSocket连接成功");
};
socket.onmessage = function(event)//连接socekt
{
console.log(event.data);
**//触发前端onMessage方法后对后台传过来的值进行判断,如果是1,就是后台单纯的给前端发送消息,并不触发后台的onMessage方法,socket.send(),就会触发后台的onMessage方法**
if(event.data=="1"){
console.log("数据更新啦");
socket.send("通知后台");
}
if(event.data=="2"){
console.log
}
};
socket.onclose = function()//关闭socekt连接
{
console.log("WebSocket连接关闭");
socket.close();
};
socket.onerror = function(obj)//连接错误
{
console.log("Socket错误");
};
}
catch (ex) {
log(ex);
}
}
else{
alert("该浏览器不支持,请切换到 Internet Explorer 10(0)模式");
}
}
后台代码修改
监听数据库
int m = userDao.insert(user);//数据库插入操作
if(m>0) {
//当插入成功是,webSocket向浏览器也就是客户端发送消息
WebSocketServlet wss = new WebSocketServlet();
try {
wss.sendMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@OnMessage
public void onMessage(String msg,Session session) {
try {
saveRedis();//先将数据存入redis
sendMessage2();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
定义两个后台给前端发送消息的方法,当前端接收到2,则说明数据缓存成功,请求后台,先从redis拿值即可
public void sendMessage() throws IOException{
//群发消息
for(WebSocketServlet item: webSocketSet){
item.session.getBasicRemote().sendText("1");
}
}
public void sendMessage2() throws IOException{
//群发消息
for(WebSocketServlet item: webSocketSet){
item.session.getBasicRemote().sendText("2");
}
}