使用websocket 实现即时消息

来源:互联网 发布:unity3d安卓真机调试 编辑:程序博客网 时间:2024/05/21 11:19

使用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);    }}
原创粉丝点击