由于自己需要做一个页面监控后台数据的自己了解了下websocket做了个小实验
小测试类
package com.pw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class Hello {
@RequestMapping("/toff")
public String toff() throws Exception{
WebSocketTest ws=new WebSocketTest();
ws.onMessage("c1##to##你好啊", "c2");
System.out.println("你好啊");
boolean stt=true;
while(stt){
if(WebSocketTest.str!=null&&!"".equals(WebSocketTest.str)){
stt=false;
}
System.out.println("11111");
}
System.out.println(WebSocketTest.str);
return "sds";
}
}
java后台websocket类
package com.pw.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
* 这里使用注释的方式来向系统指明,我的这个WebSocketTest是一个webservice。 同时指定了路径为/websocket/{uCode}
* 其中的{uCode}是一个变化的参数,在网页端动态的输入。这样我就可以通过@PathParam("uCode")这个注释在参数中获得用户的信息等等了。
*
* */
@ServerEndpoint("/websocket/{uCode}")
public class WebSocketTest {
public static String str="";
/**
* @param message
* 这里是客户端传来的消息,我这里只是简单的测试文本消息,消息的种类可以有很多种。
* @param uCode
* 这就是{uCode}中传来的路径参数,可以用来传递用户的信息。例如帐号。
* @throws Exception
* 偷懒的人总是抛出一个EXCEPTION
*/
@OnMessage
// 当有消息传来的时候进行处理的方法
public void onMessage(String message, @PathParam("uCode") String uCode)
throws Exception {
if("c1".equals(uCode)){
str=message;
}else{
System.out.println("revived:" + message);// 输出一下接收到的消息
String tem[] = message.split("##to##");// 消息的格式是
// tousername##to##message,分隔以后第一个就是要发送的用户名,第二个就是消息了
if (SessionUtils.hasConnection(tem[0])) {// 从sessionUtils中判断一下是否要发送的用户名是否已经登录,登录的话做以下操作
/* 弄个时间开始 */
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String x = sdf.format(new Date());
/* 弄个时间结束 */
/*
* 消息的发送,可以选择AsyncRemote也可以选择
* BasicRemote,区别在于AsyncRemote是不会阻塞的,系统不会去管消息是否发送完成直接占用通道去发
* 。使用它的话要用户自己去实现控制,所以我选择BasicRemote,
*/
SessionUtils.get(tem[0]).getBasicRemote()
.sendText(uCode + "##to##" + x + ":" + tem[1]);
} else {// 没有登录的话做以下操作
SessionUtils.get(uCode).getBasicRemote().sendText("用户不在线");
}
}
}
/**
* @param uCode
* 同上
* @param session
* 这个是用户建立的session信息,用来唯一标识这个用户的通信
* @throws Exception
* 你懂得
*/
@OnOpen
// 用户建立链接的时候执行的方法
public void onOpen(@PathParam("uCode") String uCode, Session session)
throws Exception {
if (SessionUtils.hasConnection(uCode)) {// 判断缓存中是否有uCode,如果有执行括号内的方法
SessionUtils.get(uCode).close();// 因为已经登录了,那么将已经登录的下线
SessionUtils.remove(uCode);// 移除掉缓存中的<uCode,Session>
SessionUtils.put(uCode, session);// 添加新的<uCode,Session>
System.out.println(uCode + "has join server");
} else {
System.out.println(uCode + "has join server");
/* 如果没有缓存相关的<uCode,Session>,那么直接添加 */
SessionUtils.put(uCode, session);
}
}
@OnClose
//客户端断开链接时执行的方法
public void onClose(@PathParam("uCode") String uCode) {
System.out.println(uCode + "has left server");
SessionUtils.remove(uCode);//直接移除就好了,session已经关闭了
System.out.println("left deal was finished");
}
@OnError
//客户端出错误的时候执行的方法
public void onError(Throwable e, Session session) {
if (SessionUtils.clients.containsValue(session)) {//移除出错的session
SessionUtils.remove(session);
}
}
}
session帮助类
package com.pw.controller;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;
/**
* Session帮助类
* @author Administrator
*
*/
public class SessionUtils {
/*<uCode,Session>的缓存*/
public static Map<String, Session> clients = new ConcurrentHashMap<String, Session>();
public static void put(String uCode, Session session) {//添加
clients.put(uCode, session);
}
public static Session get(String uCode) {//根据uCode来获取
return clients.get(uCode);
}
public static void remove(String uCode) {//根据uCode来移除
clients.remove(uCode);
}
public static void remove(Session session) {//根据session来移除
Iterator<java.util.Map.Entry<String, Session>> ito = clients.entrySet()
.iterator();
while (ito.hasNext()) {
java.util.Map.Entry<String, Session> entry = ito.next();
if (entry.getKey().equals(session))
remove(entry.getKey());
}
}
public static boolean hasConnection(String uCode) {//根据uCode来判断是否包含对应用户名的<uCode,Session>
return clients.containsKey(uCode);
}
}
html5页面代码
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>WebSoket Demo</title>
<script type="text/JavaScript">
//获取链接参数
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
//验证浏览器是否支持WebSocket协议
if (!window.WebSocket) {
alert("WebSocket not supported by this browser!");
}
var ws;
var id=getQueryString("id");
function display() {
//创建webSocket,后面的${id}与{uCode}相对应
ws=new WebSocket("ws://localhost:8080/inter/websocket/"+id);
//监听消息
ws.onmessage = function(event) {
log(event.data);
};
//绑定关闭事件
ws.onclose = function(event) {
/*这段代码的作用是,如果同一个id在其他的页面登录,那么就强制当前的页面下线,关闭。
在服务器端我们在同一个id登录时关闭了以前的socket,所以这里在关闭事件中进行操作
*/
var opened=window.open('about:blank','_self');
opened.opener=null;
opened.close();
};
//建立websocket的事件,可以用来做一些初始化操作;比如如果用户不在线其他人发送了消息我可以放在数据库里,用户一上线就调用查询方法
ws.onopen = function(event) {
};
//出现错误的时候的方法
ws.onerror =function(event){
};
}
var log = function(s) {//打印消息的方法
if (document.readyState !== "complete") {
log.buffer.push(s);
} else {
var ss=(s + "\n");
document.getElementById("contentId").innerHTML += (s + "\n");
}
}
function sendMsg(){
//这里是发送消息,我制做了c1、c2之间的通话
var msg=document.getElementById("messageId");
var client=id;
if(client=='c1') {
ws.send("c2##to##"+msg.value);//发送消息
document.getElementById("contentId").innerHTML='c1'+msg.value
}else{
ws.send("c1##to##"+msg.value);
document.getElementById("contentId").innerHTML='c2'+msg.value;
}
}
</script>
</head>
<body οnlοad="display();">
<div id="valueLabel"></div>
<textarea rows="20" cols="30" id="contentId"></textarea>
<br />
<input name="message" id="messageId" />
<button id="sendButton" onClick="javascript:sendMsg()">Send</button>
</body>
</html>