mina+webSocket 搭建兼容各版本浏览器无刷新评论实例

来源:互联网 发布:淘宝店铺促销活动方案 编辑:程序博客网 时间:2024/05/16 17:55

项目框架是别人定的,我也想使用nodeJS或者tomcat 7自带的WebSocketServlet,无奈。。

过程中碰到几个比较烦人的问题:

1、协议

2、转码

3、兼容性

对于协议和转码,我是用https://issues.apache.org/jira/browse/DIRMINA-907里面的WebSocketFilter;

对于兼容性,我是用swf代替,这里还会有个swf与java通信的问题,socket会收到<policy-file-request/>,我这里使用http://my.oschina.net/noahxiao/blog/71611的FlashPolicyServer这个类处理

下面粘部分代码实现:

public class WebSocketServer {public static final int PORT = 10000;public static void main(String[] args) {WebSocketIoHandler handler = new WebSocketIoHandler();NioSocketAcceptor acceptor = new NioSocketAcceptor();        acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new WebSocketCodecFactory()));acceptor.setHandler(handler);try {acceptor.bind(new InetSocketAddress(PORT));} catch (IOException e) {e.printStackTrace();}}}

public class WebSocketIoHandler extends IoHandlerAdapter {<span style="white-space:pre"></span>public static final String INDEX_KEY = WebSocketIoHandler.class.getName() + ".INDEX";        Map<Integer, List<IoSession>> videoIoSession = new HashMap<Integer, List<IoSession>>();        public void messageReceived(IoSession session, Object message) throws Exception {    IoBuffer buffer = (IoBuffer)message;    byte[] b = new byte[buffer.limit()];      buffer.get(b);        String code = new String(b, "utf-8");//    System.out.println(code);        if(code == null || code.equals("")){    return ;    }            //105100 --->videoId    if(code.startsWith("videoid")){    int videoId = 0;    try {    String id = code.substring(7);//        System.out.println("------------videoid"+id);        videoId = Integer.valueOf(id);} catch (Exception e) {return ;}    if(videoId <= 0){        return ;    }    ioSessionIsInMap(session, videoId);    QueryResult<VideoComments> qr = videoCommentsService.findVideoCommentsByVideoId(videoId);    //将信息推送到前台String toBrowser = structData(qr);pushMessageToIoSession(session, toBrowser, buffer);    //assic 97100100--->add    }else if(code.startsWith("add")){        try {    String info = code.substring(3);    String user = info.substring(7, info.indexOf(","));    info = info.substring(info.indexOf(",")+1);    String video = info.substring(8, info.indexOf(","));    info = info.substring(info.indexOf(",")+1);    String comment = info.substring(info.indexOf(":")+1);        int userId = Integer.valueOf(user);    int videoId = Integer.valueOf(video);    //    System.out.println("---videoId:"+videoId+"--------userId:"+userId);        //把用户评论添加到数据库    VideoComments comments = new VideoComments();    comments.setVideoId(videoId);    comments.setUserId(userId);    comments.setComment(comment);    videoCommentsService.addComments(comments);    //将信息推送到前台    String toBrowser = structData(comments);    pushMessageToAll(videoId, toBrowser, session, buffer);} catch (Exception e) {return ;}    }        }    @Override       public void sessionOpened(IoSession session) throws Exception {    System.out.println(session+"加入map");        session.setAttribute(INDEX_KEY, 0);    }        @Overridepublic void sessionClosed(IoSession session) throws Exception {    //将hash中的session移除。    synchronized (videoIoSession) {Set<Integer> keyset = videoIoSession.keySet();Iterator<Integer> iter = keyset.iterator();while (iter.hasNext()) {List<IoSession> isList = videoIoSession.get(iter.next());if(isList.contains(session)){isList.remove(session);}}    }    System.out.println(session+"退出map");    }@Override       public void sessionIdle( IoSession session, IdleStatus status ) throws Exception {       System.out.println( "IDLE " + session.getIdleCount( status ));       }private synchronized void ioSessionIsInMap(IoSession session, int videoId) {//存在videoId的list链if(videoIoSession.containsKey(videoId)){List<IoSession> isList = videoIoSession.get(videoId);//如果不存在session,将其加入到listif(!isList.contains(session)){isList.add(session);}//不存在videoId的链} else {List<IoSession> isList = new LinkedList<IoSession>();isList.add(session);videoIoSession.put(videoId, isList);}}private String structData(VideoComments comment){StringBuffer sb = new StringBuffer();sb.append(comment.getUserId()).append("-------------->").append(comment.getComment());return sb.toString();}private String structData(QueryResult<VideoComments> qr){StringBuffer sb = new StringBuffer();for (VideoComments comment : qr.getResultList()) {sb.append(comment.getUserId()).append("-------------->").append(comment.getComment());}return sb.toString();}private void pushMessageToIoSession(IoSession session, String msg, IoBuffer buffer){buffer.clear();    byte[] bb = null;try {bb = WebSocketEncoder.encode(msg);} catch (UnsupportedEncodingException e) {e.printStackTrace();}    buffer.put(bb);    buffer.flip();    session.write(buffer.duplicate());}private void pushMessageToAll(int videoId, String msg, IoSession session, IoBuffer buffer){buffer.clear();    byte[] bb = null;try {bb = WebSocketEncoder.encode(msg);} catch (UnsupportedEncodingException e) {e.printStackTrace();}    buffer.put(bb);    buffer.flip();        //push message    synchronized (videoIoSession) {    if (!videoIoSession.containsKey(videoId)) {    return ;}    List<IoSession> isList = videoIoSession.get(videoId);    for (IoSession is : isList) {    is.write(buffer.duplicate());}}}}

import org.slf4j.Logger;import org.slf4j.LoggerFactory; import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException; /** * Created with IntelliJ IDEA. * User: noah * Date: 8/8/12 * Time: 10:05 PM * To change this template use File | Settings | File Templates. */public class FlashPolicyServer {     private ServerSocket serverSocket;     private static Thread serverThread;     private int port;     private static boolean listening = true;     private Logger logger = LoggerFactory.getLogger(this.getClass());     public FlashPolicyServer() {        this(843);    }     public FlashPolicyServer(int port) {        this.port = port;    }     public void start() {         try {            serverThread = new Thread(new Runnable() {                public void run() {                    try {                         logger.info("FlashPolicyServer: Starting...");                        serverSocket = new ServerSocket(port);                         while (listening) {                            final Socket socket = serverSocket.accept();                             Thread t = new Thread(new Runnable() {                                public void run() {                                    try {                                         if (logger.isDebugEnabled()) {                                            logger.debug("FlashPolicyServer: Handling Request...");                                        }                                         socket.setSoTimeout(10000);                                         InputStream in = socket.getInputStream();                                         byte[] buffer = new byte[23];                                         if (in.read(buffer) != -1 && (new String(buffer, "ISO-8859-1")).startsWith("<policy-file-request/>")) {                                             if (logger.isDebugEnabled()) {                                                logger.debug("PolicyServerServlet: Serving Policy File...");                                            }                                             OutputStream out = socket.getOutputStream();                                              byte[] bytes = ("<?xml version=\"1.0\"?>\n" +                                                    "<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n" +                                                    "<cross-domain-policy> \n" +                                                    "   <site-control permitted-cross-domain-policies=\"master-only\"/>\n" +                                                    "   <allow-access-from domain=\"*\" to-ports=\"*\" />\n" +                                                    "</cross-domain-policy>").getBytes("ISO-8859-1");                                             out.write(bytes);                                             out.write(0x00);                                             out.flush();                                            out.close();                                        } else {                                            logger.warn("FlashPolicyServer: Ignoring Invalid Request");                                            logger.warn("  " + (new String(buffer)));                                        }                                     } catch (SocketException e) {                                        logger.error(e.getMessage(), e);                                    } catch (IOException e) {                                        logger.error(e.getMessage(), e);                                    } finally {                                        try {                                            socket.close();                                        } catch (Exception ex2) {                                        }                                    }                                }                            });                            t.start();                        }                    } catch (IOException ex) {                        logger.error("PolicyServerServlet Error---");                        logger.error(ex.getMessage(), ex);                    }                }             });            serverThread.start();        } catch (Exception ex) {            logger.error("PolicyServerServlet Error---");            logger.error(ex.getMessage(), ex);        }     }     public void stop() {        logger.info("FlashPolicyServer: Shutting Down...");         if (listening) {            listening = false;        }         if (!serverSocket.isClosed()) {            try {                serverSocket.close();            } catch (Exception ex) {            }        }    }}

<!DOCTYPE html><html>  <head>    <script type="text/javascript" src="../js/swfobject.js"></script>    <script type="text/javascript" src="../js/web_socket.js"></script>    <script type="text/javascript" src="../js/jquery-1.5.1.js"></script><script type="text/javascript">    WEB_SOCKET_SWF_LOCATION = "../js/WebSocketMain.swf";    WEB_SOCKET_DEBUG = false;    var ws;    function init() {        ws = new WebSocket("ws://192.168.0.101:10000/");        ws.onopen = function(event){ws.send("videoid108"); };        ws.onmessage = function(event){output(event.data);$("#comment").val("");};        ws.onclose = function () {            output("onClose");        };        ws.onerror = function () {            output("onError");        };    }    function output(str) {        var log = $("#log");        log.append(str).append("<br>");    }    $(function () {        $(document).ready(function () {           init();         });    });    function SendData() {        try{        var userid = 3;        var comment = $("#comment").val();        ws.send("adduserid:3,videoid:108,comment:"+comment);        $("#comment").val("");        }catch(ex){            alert(ex.message);        }    };</script></head><body><div id="log"></div><textarea rows="5" cols="100" id="comment"></textarea><button id='ToggleConnection' type="button" onclick="SendData();">发表评论</button><br /><br /></body></html>



0 0
原创粉丝点击