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

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

}

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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值