使用tomcat 作为服务器,tomcat8对websocket有很好的实现,tomcat7实现方式与其有所不同,
下面是tomcat7的实现方法:
package com.bsj.busi.servlet;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;
import com.bsj.util.redis.help.RedisHelp;
import com.bsj.util.redis.tool.eunm.MsgEunm;
/**
* 使用tomcat7运行时使用websocket
*
*
*/
@WebServlet("/websocket7")
public class WebSocketTomcat7 extends WebSocketServlet {
private static final long serialVersionUID = 1L;
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,
HttpServletRequest request) {
String relationId = request.getParameter("relationId");
int userCode = Integer.parseInt(request.getParameter("userCode"));
return new DemoMessageInbound(relationId, userCode);
}
class DemoMessageInbound extends MessageInbound {
private String relationId;
private int userCode;
public DemoMessageInbound() {
}
public DemoMessageInbound(String relationId, int userCode) {
this.relationId = relationId;
this.userCode = userCode;
}
@Override
protected void onOpen(WsOutbound outbound) {
System.out.println("websocket已经打开:" + relationId + "_" + userCode);
SessionUtils.put(relationId, userCode, outbound);
}
@Override
protected void onClose(int status) {
System.out.println("webSocket关闭:" + relationId + "_" + userCode);
SessionUtils.removeWsOutbound(relationId, userCode);
}
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
// 在这里处理二进制数据
}
/*
* (non-Javadoc) 处理业务
*
* @see
* org.apache.catalina.websocket.MessageInbound#onTextMessage(java.nio
* .CharBuffer)
*/
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
// 这里处理的是文本数据
String filteredMessage = message.toString();
String keystr = filteredMessage.split(",")[0];
int type = Integer.parseInt(filteredMessage.split(",")[1]);
StringBuffer key = new StringBuffer();
switch (type) {
case 1:
key.append(MsgEunm.COMMON.getCode() + keystr);
break;
case 2:
key.append(MsgEunm.SYSTEM.getCode() + keystr);
break;
case 3:
key.append(MsgEunm.URGENT.getCode() + keystr);
break;
}
try {
long num=RedisHelp.getRedisHelp().incr(key.toString());
if(num>0){
SessionUtils.broadcastWsOutbound(relationId, userCode,
(num-1 )+ "");
RedisHelp.getRedisHelp().decr(key.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
這是操作类:
package com.bsj.busi.servlet;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;
import org.apache.catalina.websocket.WsOutbound;
public class SessionUtils {
private static Map<String, WsOutbound> clientw = new ConcurrentHashMap<String, WsOutbound>();
public static Map<String, Session> clients = new ConcurrentHashMap<String, Session>();
private static ThreadLocal<WsOutbound> outboundLocal = new ThreadLocal<WsOutbound>();
private static ThreadLocal<Integer> countWsOutbound = new ThreadLocal<Integer>();
public static void put(String relationId, int userCode, WsOutbound outbound) {
clientw.put(getKey(relationId, userCode), outbound);
}
public static void put(String relationId, int userCode, Session session) {
clients.put(getKey(relationId, userCode), session);
}
public static Session getSession(String relationId, int userCode) {
return clients.get(getKey(relationId, userCode));
}
public static void removeSession(String relationId, int userCode) {
clients.remove(getKey(relationId, userCode));
}
/**
* 判断是否有连接
*
* @param relationId
* @param userCode
* @return
*/
public static boolean hasConnectionSession(String relationId, int userCode) {
return clients.containsKey(getKey(relationId, userCode));
}
private static WsOutbound GetWsOutbound(String relationId, int userCode) {
countWsOutbound.set(countWsOutbound.get() + 1);
if (countWsOutbound.get() >= 10) {
return null;
} else {
WsOutbound outbound = null;
try {
outbound = clientw.get(getKey(relationId, userCode));
} catch (Exception e) {
outbound = GetWsOutbound(relationId, userCode);
}
if (outbound == null) {
outbound = GetWsOutbound(relationId, userCode);
}
return outbound;
}
}
public static WsOutbound getWsOutbound(String relationId, int userCode) {
countWsOutbound.set(0);
if (outboundLocal.get() == null) {
outboundLocal.set(GetWsOutbound(relationId, userCode));
}
return outboundLocal.get();
}
public static Boolean hasConnectionWsOutbound(String relationId,
int userCode) {
return clientw.containsKey(getKey(relationId, userCode));
}
public static void removeWsOutbound(String relationId, int userCode) {
if (hasConnectionWsOutbound(relationId, userCode)) {
clientw.remove(getKey(relationId, userCode));
}
}
private static String getKey(String relationId, int userCode) {
return relationId + "_" + userCode;
}
// 将数据传回客户端
public static synchronized void broadcastWsOutbound(String relationId,
int userCode, String message) {
try {
CharBuffer buffer = CharBuffer.wrap(message);
getWsOutbound(relationId, userCode).writeTextMessage(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
// 将数据传回客户端
public static synchronized void broadcastSession(String relationId,
int userCode, String message) {
try {
getSession(relationId, userCode).getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
這是tomcat8的实现:
package com.bsj.busi.servlet;
import java.io.IOException;
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.bsj.util.redis.help.RedisHelp;
import com.bsj.util.redis.tool.eunm.MsgEunm;
/**
* 使用tomcat8运行时使用websocket
*
*
*/
@ServerEndpoint("/websocket8/{relationId}/{userCode}")
public class WebSocketTomcat8 {
/**
* 当服务器接收到客户端发送的消息时所调用的方法 该方法可能包含一个javax.websocket.Session可选参数
* 如果有这个参数,容器将会把当前发送消息客户端的连接Session注入进去
*/
@OnMessage
public void onMessage(@PathParam("relationId") String relationId,
@PathParam("userCode") int userCode, String message, Session session)
throws IOException, InterruptedException {
// 打印从客户端获取到的信息
String keystr = message.split(",")[0];
int type = Integer.parseInt(message.split(",")[1]);
StringBuffer key = new StringBuffer();
switch (type) {
case 1:
key.append(MsgEunm.COMMON.getCode() + keystr);
break;
case 2:
key.append(MsgEunm.SYSTEM.getCode() + keystr);
break;
case 3:
key.append(MsgEunm.URGENT.getCode() + keystr);
break;
}
try {
// 向客户端第发送信息
long num = RedisHelp.getRedisHelp().incr(key.toString());
if (num > 0) {
SessionUtils.broadcastSession(relationId, userCode, (num - 1)
+ "");
RedisHelp.getRedisHelp().decr(key.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 当一个新用户连接时所调用的方法 该方法可能包含一个javax.websocket.Session可选参数
* 如果有这个参数,容器将会把当前发送消息客户端的连接Session注入进去
*/
@OnOpen
public void onOpen(@PathParam("relationId") String relationId,
@PathParam("userCode") int userCode, Session session) {
System.out.println("连接成功:" + relationId + "," + userCode);
SessionUtils.put(relationId, userCode, session);
}
/** 当一个用户断开连接时所调用的方法 */
@OnClose
public void onClose(@PathParam("relationId") String relationId,
@PathParam("userCode") int userCode) {
System.out.println("连接关闭:" + relationId + "," + userCode);
SessionUtils.removeSession(relationId, userCode);
}
}