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
- mina+webSocket 搭建兼容各版本浏览器无刷新评论实例
- 各版本浏览器兼容
- Ajax无刷新评论
- 无刷新评论模拟
- AJAX无刷新评论
- 无刷新视频评论
- javascript 无刷新评论
- $.ajax无刷新评论
- 评论无闪烁刷新
- 练习:js无刷新评论
- php jquery 无刷新评论
- HTML页面无刷新评论
- Jquery实现无刷新评论
- js实现无刷新评论
- js实现无刷新评论
- Flask 页面无刷新评论
- 解决浏览器不兼容websocket
- HTML5-webSocket兼容低浏览器
- ios UIImageView 设置图片 不变形
- 栈的链式存储
- python 加载第三方库 xlrd-0.9.2
- Android中Service类onStartCommand的返回值问题
- ZSTACK 中发射功率设置问题
- mina+webSocket 搭建兼容各版本浏览器无刷新评论实例
- VS2012动态链接lua
- 和WiFi共享精灵一起成长
- 使用cscope
- session与cookie的区别
- 异步任务和网络编程详细学习。四大组件了解下
- Android App接入微信开放平台注意事项
- 软件加密保护方案
- 人生就是不断的选择