使用websocket 实现即时消息

使用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);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值