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

来源:互联网 发布:linux vi 怎么复制 编辑:程序博客网 时间:2024/05/16 15:50

之前做了一篇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--;    }}

前台的页面没有改变,经测试,可行!!!
代码我已经上传到网上,源码下载

0 0
原创粉丝点击