您的位置:首页 > 运维架构 > Tomcat

HTML5 WebSocket+Tomcat8实现真●Web版即时聊天室(单人+多人)

2015-10-13 13:42 686 查看
之前做了一篇tomcat7的websocket聊天室,这是基于tomcat7和jdk1.7下的,有的项目是在tomcat8下的,这个时候就会有问题,因为8下面不支持那种写法,它是以注解的方式来实现websocket,参照HTML5 WebSocket+Tomcat实现Web版即时聊天室 ,下面就介绍一下如何在8下面实现聊天室,多人加单人!

最重要的是获取每个用户登录的session,这里的session是HttpSession,websocket自带了session,但在实际项目中我们可能只用到第一种,如何在8下面获取呢?

这里要写个类,来继承ServerEndpointConfig.Configurator:

package com.socket;

import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

import javax.servlet.http.HttpSession;

public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator  {

@Override
public void modifyHandshake(ServerEndpointConfig config,HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
config.getUserProperties().put(HttpSession.class.getName(), httpSession);
}

}


再在websocket服务里添加这个配置,就像这样

@ServerEndpoint(value = "/websocket",configurator=GetHttpSessionConfigurator.class)


我将两个HttpSession放在一个map里,由用户进入,就put进去,如下

private static final Map<HttpSession,ChatServlet> onlineUsers = new HashMap<HttpSession, ChatServlet>();


代码为

package com.socket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import utils.MessageUtil;

@ServerEndpoint(value = "/websocket",configurator=GetHttpSessionConfigurator.class)
public class ChatServlet {

private static final Map<HttpSession,ChatServlet> onlineUsers = new HashMap<HttpSession, ChatServlet>();

private static int onlineCount = 0;

private HttpSession httpSession;

private Session session;

@OnOpen
public void onOpen(Session session,EndpointConfig config){

this.session = session;
this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
if(httpSession.getAttribute("user") != null){
onlineUsers.put(httpSession, this);
}
String names = getNames();
String content = MessageUtil.sendContent(MessageUtil.USER,names);
broadcastAll(content);
addOnlineCount();           //在线数加1
System.out.println("有新连接加入!当前在线人数为" + onlineUsers.size());
}

@OnClose
public void onClose(){
onlineUsers.remove(this);  //从set中删除
subOnlineCount();           //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}

@OnMessage
public void onMessage(String message, Session session) throws IOException {

HashMap<String,String> messageMap = MessageUtil.getMessage(message);    //处理消息类
String fromName = messageMap.get("fromName");    //消息来自人 的userId
String toName = messageMap.get("toName");       //消息发往人的 userId
String mapContent = messageMap.get("content");

if(toName.isEmpty()){
sendOffLine(fromName,toName);
return;
}

if("all".equals(toName)){
String msgContentString = fromName + "对所有人说: " + mapContent;   //构造发送的消息
String content = MessageUtil.sendContent(MessageUtil.MESSAGE,msgContentString);
broadcastAll(content);
}else{
try {
String content = MessageUtil.sendContent(MessageUtil.MESSAGE,mapContent);
singleChat(fromName,toName,content);
} catch (IOException e) {
e.printStackTrace();
}
}

System.out.println("来自客户端的消息:" + message);
broadcastAll(message);
}

private void singleChat(String fromName, String toName, String mapContent) throws IOException {
String msgContentString = fromName + "对" + toName + "说: " + mapContent;
String contentTemp = MessageUtil.sendContent(MessageUtil.MESSAGE,msgContentString);
boolean isExit = false;
for (HttpSession key : onlineUsers.keySet()) {
if(key.getAttribute("user").equals(toName)){
isExit = true;
}
}
if(isExit){
for (HttpSession key : onlineUsers.keySet()) {
if(key.getAttribute("user").equals(fromName) || key.getAttribute("user").equals(toName)){
onlineUsers.get(key).session.getBasicRemote().sendText(contentTemp);
}
}
}else{
String content = MessageUtil.sendContent(MessageUtil.MESSAGE,"客服不在线请留言...");
broadcastAll(content);
}

}
private void sendOffLine(String fromName, String toName) throws IOException {
String msgContentString = toName + "不在线";
String content = MessageUtil.sendContent(MessageUtil.MESSAGE,msgContentString);
for (HttpSession key : onlineUsers.keySet()) {
if(key.getAttribute("user").equals(fromName) || key.getAttribute("user").equals(toName)){
onlineUsers.get(key).session.getBasicRemote().sendText(content);
}
}
}
private static void broadcastAll(String msg) {
for (HttpSession key : onlineUsers.keySet()) {
try {
onlineUsers.get(key).session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}

@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}

private String getNames() {
String names = "";
for (HttpSession key : onlineUsers.keySet()) {
String name = (String) key.getAttribute("user");
names += name + ",";
}
String namesTemp = names.substring(0,names.length()-1);
return namesTemp;
}

public static synchronized int getOnlineCount() {
return onlineCount;
}

public static synchronized void addOnlineCount() {
ChatServlet.onlineCount++;
}

public static synchronized void subOnlineCount() {
ChatServlet.onlineCount--;
}

}


前台的页面没有改变,经测试,可行!!!

代码我已经上传到网上,源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: