一、写在前面

   要求做一个,后台发布信息,前台能即时得到通知的消息推送功能。网上搜了也有很多方式,ajax的定时询问,Comet方式,Server-Sent方式,以及websocket。表示除了定时询问外,就websocket相对简单点。

二、实现

  实现类java代码:

  1. package cn.xm.mall.websocket.controller;
  2.  
  3. import java.io.IOException;
  4. import java.nio.ByteBuffer;
  5. import java.nio.CharBuffer;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Date;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. import java.util.Set;
  11.  
  12. import javax.servlet.annotation.WebServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14.  
  15. import org.apache.catalina.websocket.MessageInbound;
  16. import org.apache.catalina.websocket.StreamInbound;
  17. import org.apache.catalina.websocket.WebSocketServlet;
  18. import org.apache.catalina.websocket.WsOutbound;
  19.  
  20. @WebServlet("/webSocket.do")
  21. public class WebSocketServletController extends WebSocketServlet {
  22. private final Map<Integer, WsOutbound> map = new HashMap<Integer, WsOutbound>();
  23. private static final long serialVersionUID = -1058445282919079067L;
  24. @Override
  25. protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request) {
  26. // StreamInbound:基于流的WebSocket实现类(带内流),应用程序应当扩展这个类并实现其抽象方法onBinaryData和onTextData。
  27. return new ChatMessageInbound();
  28. }
  29. class ChatMessageInbound extends MessageInbound {
  30. // MessageInbound:基于消息的WebSocket实现类(带内消息),应用程序应当扩展这个类并实现其抽象方法onBinaryMessage和onTextMessage。
  31. @Override
  32. protected void onOpen(WsOutbound outbound) {
  33. map.put(outbound.hashCode(), outbound);
  34. super.onOpen(outbound);
  35. }
  36. @Override
  37. protected void onClose(int status) {
  38. map.remove(getWsOutbound().hashCode());
  39. super.onClose(status);
  40. }
  41. @Override
  42. protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
  43. }
  44. @Override
  45. protected void onTextMessage(CharBuffer buffer) throws IOException {
  46. String msg = buffer.toString();
  47. Date date = new Date();
  48. SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  49. //msg = " <font color=green>匿名用戶 " + sdf.format(date) + "</font><br/> " + msg;
  50. broadcast(msg);
  51. }
  52. private void broadcast(String msg) {
  53. Set<Integer> set = map.keySet();
  54. for (Integer integer : set) {
  55. WsOutbound outbound = map.get(integer);
  56. CharBuffer buffer = CharBuffer.wrap(msg);
  57. try {
  58. outbound.writeTextMessage(buffer);
  59. outbound.flush();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }
  65. }
  66. }

前台连接websocket 代码 写到了js里,页面直接引用,就和websocket连通了。

  1. /**
  2. * WebSocket消息推送
  3. * @Copyright Copyright (c) 2006
  4. * @author Guapo
  5. * @see DESCore
  6. */
  7. $(function() {
  8. var loginNameCookie=$.cookie('memberInfo');
  9. if(typeof(loginNameCookie) == "undefined" || loginNameCookie==null || loginNameCookie==''){}else{
  10. chat();
  11. }
  12.  
  13. });
  14.  
  15. var socket;
  16.  
  17. var chat = function() {
  18.  
  19. socket = new WebSocket('ws://XXXXX/webSocket.do');
  20.  
  21. socket.onopen = function(event) {
  22.  
  23. console.info("<font color=green>连接成功!</font>");
  24.  
  25. };
  26. socket.onmessage = function(event) {
  27. if("pms"==event.data){
  28. appendInsideLetter();//这里是后台send一个pms参数类型,前台得知后,异步查询后台通知的资讯,然后页面通知动作的方法
  29. }
  30. };
  31.  
  32. socket.onclose = function(event) {
  33. console.info("<font color=green>连接断开!</font>");
  34.  
  35. };
  36. if (socket == null) {
  37. console.info("<font color=green>连接失败!</font>");
  38.  
  39. }
  40. };
  41. var send = function() {

后台同理和前台连接同一个websoket后。在发布完信息后,调用一下send方法。代码如下

  1. var socket;
  2.  
  3. var chat = function() {
  4.  
  5. socket = new WebSocket('ws://www.simaakj.com/webSocket.do');
  6.  
  7. socket.onopen = function(event) {
  8. console.info("<font color=green>连接成功!</font>");
  9. send();//后台连接的时候,就通知了一下。
  10.  
  11. };
  12. socket.onmessage = function(event) {
  13.  
  14. };
  15.  
  16. socket.onclose = function(event) {
  17. console.info("<font color=green>连接断开!</font>");
  18.  
  19. };
  20. if (socket == null) {
  21. console.info("<font color=green>连接失败!</font>");
  22.  
  23. }
  24. };
  25. var send = function() {
  26.  
  27. socket.send("pms");
  28.  
  29. }

后台操作完,调用 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中添加的 

  1. proxy_http_version 1.1;
  2. proxy_set_header Upgrade $http_upgrade;
  3. proxy_set_header Connection "upgrade";

拾人牙慧篇之——基于HTML5中websocket来实现消息推送功能的更多相关文章

  1. ZH奶酪:基于ionic.io平台的ionic消息推送功能实现

    Hybrid App越来越火,Ionic的框架也逐渐被更多的人熟知. 在mobile app中,消息推送是很必要的一个功能. 国内很多ionic应用的推送都是用的极光推送,最近研究了一下Ionic自己 ...

  2. 基于ajax与msmq技术的消息推送功能实现

    周末在家捣鼓了一下消息推送的简单例子,其实也没什么技术含量,欢迎大伙拍砖.我设计的这个推送demo是基于ajax长轮询+msmq消息队列来实现的,具体交互过程如下图: 先说说这个ajax长轮询,多长时 ...

  3. springboot+websocket+sockjs进行消息推送【基于STOMP协议】

    springboot+websocket+sockjs进行消息推送[基于STOMP协议] WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就 ...

  4. WinForm中 Asp.Net Signalr消息推送测试实例

    p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...

  5. Worktile中百万级实时消息推送服务的实现

    Worktile中百万级实时消息推送服务的实现 出自:http://blog.jobbole.com/81125/

  6. 基于FCM的消息推送功能

    需求背景 我方项目需要支持客户端消息推送,iOS终端可以借由苹果本身的apns很方便的实现,但是对于Android来说,必须集成第三方的SDK来处理.考虑到项目需要以及成本,我们选择使用谷歌的FCM框 ...

  7. HTML5中的SSE(服务器推送技术)

    本文原链接:https://cloud.tencent.com/developer/article/1194063 SSE技术详解:一种全新的HTML5服务器推送事件技术 前言 概述 基本介绍 与We ...

  8. springboot整合websocket实现一对一消息推送和广播消息推送

    maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  9. mqtt协议实现 java服务端推送功能(三)项目中给多个用户推送功能

    接着上一篇说,上一篇的TOPIC是写死的,然而在实际项目中要给不同用户 也就是不同的topic进行推送 所以要写活 package com.fh.controller.information.push ...

随机推荐

  1. 方便使用FFMPEG的经验

    FFMPEG是命令行工具,因此使用起来多少还是会有些不方便.在这记录两点方便使用FFMPEG的方法: 1.任何目录下都可以使用FFMPEG 问题描述:需要转码(播放)的时候,需要把ffmpeg.exe ...

  2. python类定义

    在我的收藏中有一篇特别详细的类讲解 此处部分内容引自:http://blog.sina.com.cn/s/blog_59b6af690101bfem.html class myclass: 'this ...

  3. 使用OC和Swift两种语言写一个发射烟花的小项目

    OC与Swift两种实现方式基本上区别不大,主要是在一些对象或方法的调用方式不同,附带源码. OC代码样式: self.view.backgroundColor = [UIColor blackCol ...

  4. 网站开发进阶(三十二)HTML5之FileReader的使用

    HTML5之FileReader的使用 HTML5定义了FileReader作为文件API的重要成员用于读取文件,根据W3C的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型 ...

  5. 关于Android自定义view 你所需要知道的基本函数

    开始时之前想吐槽一句..iphone的闹钟,12小时制.我成功的把闹钟订到了下午5:00 导致错过一班飞机.心疼改签费. 候机ing,没有事做,来写一下学习自定义view必须掌握的基本函数.这里只挑一 ...

  6. 《java入门第一季》之Arrays类

    前面介绍了排序问题(见博客http://blog.csdn.net/qq_32059827/article/details/51362390):二分查找问题(见博客http://blog.csdn.n ...

  7. 说说nio----1

    既然说到了nio,就得谈以下几个问题 为什么会出现新io,"旧io"有什么问题吗? ok,一步一步来,先给大家看几个例子: 1单线程的服务器程序 import java.net.* ...

  8. 生产者消费者的java实现

    先看最简单的,也就是缓冲区的容量为1 缓冲区容量为1 import java.util.List; public class ProducerAndConsumer2 { static class A ...

  9. LeetCode之“链表”:Remove Duplicates from Sorted List && Remove Duplicates from Sorted List II

    1. Remove Duplicates from Sorted List 题目链接 题目要求: Given a sorted linked list, delete all duplicates s ...

  10. C语言之归并排序

    即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列. 上代码: #include <stdio.h> #include <stdlib.h> #define m ...