拾人牙慧篇之——基于HTML5中websocket来实现消息推送功能
一、写在前面
要求做一个,后台发布信息,前台能即时得到通知的消息推送功能。网上搜了也有很多方式,ajax的定时询问,Comet方式,Server-Sent方式,以及websocket。表示除了定时询问外,就websocket相对简单点。
二、实现
实现类java代码:
- package cn.xm.mall.websocket.controller;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.CharBuffer;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Set;
- 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;
- @WebServlet("/webSocket.do")
- public class WebSocketServletController extends WebSocketServlet {
- private final Map<Integer, WsOutbound> map = new HashMap<Integer, WsOutbound>();
- private static final long serialVersionUID = -1058445282919079067L;
- @Override
- protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request) {
- // StreamInbound:基于流的WebSocket实现类(带内流),应用程序应当扩展这个类并实现其抽象方法onBinaryData和onTextData。
- return new ChatMessageInbound();
- }
- class ChatMessageInbound extends MessageInbound {
- // MessageInbound:基于消息的WebSocket实现类(带内消息),应用程序应当扩展这个类并实现其抽象方法onBinaryMessage和onTextMessage。
- @Override
- protected void onOpen(WsOutbound outbound) {
- map.put(outbound.hashCode(), outbound);
- super.onOpen(outbound);
- }
- @Override
- protected void onClose(int status) {
- map.remove(getWsOutbound().hashCode());
- super.onClose(status);
- }
- @Override
- protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
- }
- @Override
- protected void onTextMessage(CharBuffer buffer) throws IOException {
- String msg = buffer.toString();
- Date date = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
- //msg = " <font color=green>匿名用戶 " + sdf.format(date) + "</font><br/> " + msg;
- broadcast(msg);
- }
- private void broadcast(String msg) {
- Set<Integer> set = map.keySet();
- for (Integer integer : set) {
- WsOutbound outbound = map.get(integer);
- CharBuffer buffer = CharBuffer.wrap(msg);
- try {
- outbound.writeTextMessage(buffer);
- outbound.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
前台连接websocket 代码 写到了js里,页面直接引用,就和websocket连通了。
- /**
- * WebSocket消息推送
- * @Copyright Copyright (c) 2006
- * @author Guapo
- * @see DESCore
- */
- $(function() {
- var loginNameCookie=$.cookie('memberInfo');
- if(typeof(loginNameCookie) == "undefined" || loginNameCookie==null || loginNameCookie==''){}else{
- chat();
- }
- });
- var socket;
- var chat = function() {
- socket = new WebSocket('ws://XXXXX/webSocket.do');
- socket.onopen = function(event) {
- console.info("<font color=green>连接成功!</font>");
- };
- socket.onmessage = function(event) {
- if("pms"==event.data){
- appendInsideLetter();//这里是后台send一个pms参数类型,前台得知后,异步查询后台通知的资讯,然后页面通知动作的方法
- }
- };
- socket.onclose = function(event) {
- console.info("<font color=green>连接断开!</font>");
- };
- if (socket == null) {
- console.info("<font color=green>连接失败!</font>");
- }
- };
- var send = function() {
后台同理和前台连接同一个websoket后。在发布完信息后,调用一下send方法。代码如下
- var socket;
- var chat = function() {
- socket = new WebSocket('ws://www.simaakj.com/webSocket.do');
- socket.onopen = function(event) {
- console.info("<font color=green>连接成功!</font>");
- send();//后台连接的时候,就通知了一下。
- };
- socket.onmessage = function(event) {
- };
- socket.onclose = function(event) {
- console.info("<font color=green>连接断开!</font>");
- };
- if (socket == null) {
- console.info("<font color=green>连接失败!</font>");
- }
- };
- var send = function() {
- socket.send("pms");
- }
后台操作完,调用 chat();既可推送告知前台成功。
三、遇到的问题,总结
0、The hierarchy of the type MyMessageInbound is inconsistent。一开始遇到这个问题,原因是缺少包,不仅仅需要tomcat中的catalina.jar以及websocket-api.jar。还需要tomcat-coyote-7.0.27.jar
1、以上代码放到本地后,开发发现连不上,发现需要在登录过滤把webSocket.do去掉,去掉之后,本地运行好使了。
2、放到环境中后,发现又有问题,原来是环境用到了Nginx,导致websoket不好使,百度了下解决办法,在Nginx配置中加入以下代码,就好使了。
我是在reverse-proxy.conf中添加的
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
拾人牙慧篇之——基于HTML5中websocket来实现消息推送功能的更多相关文章
- ZH奶酪:基于ionic.io平台的ionic消息推送功能实现
Hybrid App越来越火,Ionic的框架也逐渐被更多的人熟知. 在mobile app中,消息推送是很必要的一个功能. 国内很多ionic应用的推送都是用的极光推送,最近研究了一下Ionic自己 ...
- 基于ajax与msmq技术的消息推送功能实现
周末在家捣鼓了一下消息推送的简单例子,其实也没什么技术含量,欢迎大伙拍砖.我设计的这个推送demo是基于ajax长轮询+msmq消息队列来实现的,具体交互过程如下图: 先说说这个ajax长轮询,多长时 ...
- springboot+websocket+sockjs进行消息推送【基于STOMP协议】
springboot+websocket+sockjs进行消息推送[基于STOMP协议] WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就 ...
- WinForm中 Asp.Net Signalr消息推送测试实例
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- Worktile中百万级实时消息推送服务的实现
Worktile中百万级实时消息推送服务的实现 出自:http://blog.jobbole.com/81125/
- 基于FCM的消息推送功能
需求背景 我方项目需要支持客户端消息推送,iOS终端可以借由苹果本身的apns很方便的实现,但是对于Android来说,必须集成第三方的SDK来处理.考虑到项目需要以及成本,我们选择使用谷歌的FCM框 ...
- HTML5中的SSE(服务器推送技术)
本文原链接:https://cloud.tencent.com/developer/article/1194063 SSE技术详解:一种全新的HTML5服务器推送事件技术 前言 概述 基本介绍 与We ...
- springboot整合websocket实现一对一消息推送和广播消息推送
maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- mqtt协议实现 java服务端推送功能(三)项目中给多个用户推送功能
接着上一篇说,上一篇的TOPIC是写死的,然而在实际项目中要给不同用户 也就是不同的topic进行推送 所以要写活 package com.fh.controller.information.push ...
随机推荐
- 清除行内元素之间的HTML空白
原文连接:Remove Whitespace Between Inline-Block Elements 原文日期: 2013年8月27日 翻译日期: 2013年8月28日 至今我还记得年轻是在IE6 ...
- mysql聚集索引
转自http://www.cnblogs.com/tuyile006/archive/2009/08/28/1555615.html 微软的SQL SERVER提供了两种索引:聚集索引(cluster ...
- 【面试必备】Swift 面试题及其答案
原文:Swift Interview Questions and Answers 原作者:Antonio Bello 原作者介绍: Antonio 拥有丰富的编程经验.他开始编程的时候,内存单位还是 ...
- Android studio使用git-android学习之旅(79)
首先我参考了hello_my_show和梦痕_sky的博客,表示感谢 android studio对于git的支持是很好的,这节课我们拉讲解怎么使用git可视化工具来clone project和提交修 ...
- 【面试笔试算法】牛客网一站通Offer编程题2016.4.19
牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...
- uGUI使用代码动态添加Button.OnClick()事件(Unity3D开发之十二)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/42705885 ...
- VS2005的数据断点功能
多年前在VS2005强大的条件断点功能里面讨论过VS2005的条件断点功能. 其实在VS2005里面还有比较好用的(为什么我不用很牛逼呢?因为和OD比起来实在是太简陋了,但是使用上还是比较方便的)内存 ...
- TrueType和Bitmap字体的区别
只要标签的文本从不变化,在cocos2D中渲染TrueType和bitmap字体的性能是相同的.它们都仅仅像精灵那样绘制. 如果你希望大量的标签使用相同字体,则bitmap字体将更快.因为bitmap ...
- 通过服务修改widgetUI
public static void updateAppWidget(Context context, String displayMsg) { AppWidgetManager appWidgetM ...
- LeetCode之“数学”:Rectangle Area
题目链接 题目要求: Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle i ...