消息推送二 之webSocket

友情提示: 消息推送的介绍可以参考http://www.cnblogs.com/dahuandan/p/6816173.html

什么是webSocket

webSocket是为解决客户端与服务端实时通信而产生的技术,其本质是使用一个TCP连接进行双向通讯,可以用来Web服务端的消息推送,被IETF定义为标准协议。

优点

相对于传统的HTTP轮询技术而言,webSocket是建立一次TCP连接进行客户端与服务端的双向通讯,减少了传统轮询技术频繁地向服务器发起请求,另外webSocket的Header相比HTTP的非常小。

helloWord

环境准备



Spring4.0版本以上

tomcat8

Constants.java



package demo;

/**
 * webSocket常量
 */
public class Constants {

    /**
     * http session 中 用户名的key值
     */
    public static String SESSION_USERNAME = "session_username";

    /**
     * websocket session 中 用户名的key值
     */
    public static String WEBSOCKET_USERNAME = "websocket_username";
}

WebSocketConfig.java



package demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
 * 注册websocket
 */
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{

    public void registerWebSocketHandlers(WebSocketHandlerRegistry reg) {
        String websocket_url = "/webSocketServer";                     //设置websocket的地址
        reg.addHandler(systemWebSocketHandler(), websocket_url)        //注册到Handler
           .addInterceptors(new WebSocketInterceptor());               //注册到Interceptor

        //提供SockJS支持(主要是兼容ie8)
        String sockjs_url    = "/sockjs/webSocketServer";           //设置sockjs的地址
        reg.addHandler(systemWebSocketHandler(),sockjs_url )        //注册到Handler
           .addInterceptors(new WebSocketInterceptor())                //注册到Interceptor
           .withSockJS();                                              //支持sockjs协议 

    }

    @Bean
    public WebSocketHandler systemWebSocketHandler(){
        return new MyWebSocketHandler();
    }

}

WebSocketInterceptor.java



package demo;
import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

/**
 * WebSocket握手拦截器
 */
public class WebSocketInterceptor implements HandshakeInterceptor {

    //握手前
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
            Map<String, Object> attr) throws Exception {

        if (request instanceof ServletServerHttpRequest) {

            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;

            String user = servletRequest.getServletRequest().getParameter("user");
            attr.put(Constants.WEBSOCKET_USERNAME, user);
        }
        return true;
    }

    //握手后
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
            WebSocketHandler handler, Exception e) {
    }
}

MyWebSocketHandler.java



package demo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

/**
 * WebSocket处理器
 */
public class MyWebSocketHandler implements WebSocketHandler {

    /**
     * WebSocketSession容器
     */
    private static final List<WebSocketSession> users = new ArrayList<WebSocketSession>();

    //建立连接后的函数
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        users.add(session);
    }

    //消息处理
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> ws_msg) throws Exception {
//        String user = (String)session.getAttributes().get(Constants.WEBSOCKET_USERNAME);

        sendMessageToUsers(new TextMessage("received at server: " + ws_msg.getPayload()));
    }

    //关闭连接后的函数
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        users.remove(session);
    }

    //异常处理
    @Override
    public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {

        if(session.isOpen())
            session.close();

        users.remove(session);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 给所有在线用户发送消息
     * @param message
     * @throws IOException
     */
    public void sendMessageToUsers(TextMessage message) throws IOException {
        for (WebSocketSession user : users) {
            if (user.isOpen())
                user.sendMessage(message);
        }
    }

    /**
     * 给某个用户发送消息
     * @param userName
     * @param message
     * @throws IOException
     */
    public void sendMessageToUser(String userName, TextMessage message) throws IOException {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get(Constants.WEBSOCKET_USERNAME).equals(userName)) {
               if (user.isOpen()) {
                   user.sendMessage(message);
               }
            }
        }
    }

}

index.jsp



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>websocket</title>

<script src="jquery-1.10.2.js"></script>
<script src="sockjs-0.3.min.js"></script>
<script>

$(function(){
    var webSocket = newWebSocket();

    sendMessage(webSocket);
});

/**
 * 创建webSocket
 */
function newWebSocket(){
    var webSocket;

    if (‘WebSocket‘ in window)
        webSocket = new WebSocket("ws://localhost:8080/websocket/webSocketServer?user=123");

    else if (‘MozWebSocket‘ in window)
        webSocket = new MozWebSocket("ws://localhost:8080/websocket/webSocketServer");

    else
        webSocket = new SockJS("http://localhost:8080/websocket/sockjs/webSocketServer");

    //打开webSocket连接
    webSocket.onopen = function (evnt) {
    };

    //接收信息
    webSocket.onmessage = function (evnt) {
        $("#console").append("(<font color=‘red‘>"+evnt.data+"</font>)</br>")
    };

    //错误处理
    webSocket.onerror = function (evnt) {
    };

    //关闭webSocket
    webSocket.onclose = function (evnt) {
    }

    return webSocket;
}

/**
 * 发送信息
 */
function sendMessage(webSocket){

    $("#send").click(function(){
        webSocket.send($("#message").val());
    });
}
</script>
</head>

<body>
    <div>
        <textarea id="message" style="width: 350px">send message!</textarea>
    </div>

    </br>

    <div>
        <button id="send">send</button>
    </div>

    <div id="console"></div>
</body>
</html>

spring.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-4.1.xsd">

      <context:annotation-config />
</beans>

springmvc.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

    <mvc:annotation-driven/>
    <context:component-scan base-package="demo*"/>

    <!-- 静态资源解析 包括 :js、css、img、..
         location: 资源所在的本地路径,建议不要放在webInf下
         mapping :url的访问路径, **代表包含resource/路径后的所有子目录
     -->
     <mvc:resources location="/" mapping="/**"/>
</beans>

web.xml



<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>websocketDemo</display-name>    

    <!-- 加载spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/spring/spring.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- springmvc前端控制器,rest配置 -->
    <servlet>
        <servlet-name>springmvc_rest</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等) 如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml) -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc_rest</servlet-name>
        <!-- 第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
               第二种:/,所以访问的地址都由DispatcherServlet进行解析, 使用此种方式可以实现 RESTful风格的url(对于静态文件的解析需要配置不让DispatcherServlet进行解析)
               第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时, 仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- post乱码过虑器 -->
    <!-- 除了加过滤器,由于tomcat默认编码ISO-8859-1,还需要修改 %tomcat%/conf/server.xml Connector 标签加属性 URIEncoding="UTF-8" -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

测试

打开多个窗口,分别输入http://localhost:8080/websocket/index.jsp, 然后在某一窗口发送消息的时候,其他窗口都能接收到:

时间: 2024-10-08 03:43:05

消息推送二 之webSocket的相关文章

C#解惑3——WebSocket与消息推送(转)

目录 一.Socket简介 二.WebSocket简介与消息推送 三.WebSocket客户端 四.WebSocket服务器端 五.测试运行 六.小结与消息推送框架 6.1.开源Java消息推送框架 Pushlet 6.2.开源DotNet消息推送框架SignalR 七.代码下载 7.1.Java实现的服务器端代码与客户端代码下载 7.2.DotNet服务器端手动连接实现代码下载 7.3.DotNet下使用SuperWebSocket三方库实现代码下载 B/S结构的软件项目中有时客户端需要实时的

spring websocket 和socketjs实现单聊群聊,广播的消息推送详解

spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 我们知道,传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而

在Spring Boot框架下使用WebSocket实现消息推送

Spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目(使用Spring Boot开发Web项目)以及怎样为我们的Project添加HTTPS的支持(使用Spring Boot开发Web项目(二)之添加HTTPS支持),在这两篇文章的基础上,我们今天来看看如何在Spring Boot中使用WebSocket. 什么是WebSocket WebSocket为浏览器和服务器之间提供了双工异步通信功能,也就是说我们可以利用浏览器给服务器发送消息,

WebSocket与消息推送

B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链接,但不容易直接完成实时的消息推送功能,如聊天室.后台信息提示.实时更新数据等功能,但通过polling.Long polling.长连接.Flash Socket以及HTML5中定义的WebSocket能完成该功能需要. 一.Socket简介 Socket又称"套接字",应用程序通常通过

C(++) Websocket消息推送---GoEasy

Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送速度快,代码简单易懂上手快浏览器兼容性:GoEasy推送支持websocket 和polling两种连接方式,从而可以支持IE6及其以上的所有版本,同时还支持其它浏览器诸如Firefox, Chrome, Safari 等等.支 持不同的开发语言:   GoEasy推送提供了Restful API接口,无论你的后台程序用的是哪种语言都可以通过RestfulAPI来实现后台实时推送.

node.js Websocket消息推送---GoEasy

Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送速度快,代码简单易懂上手快浏览器兼容性:GoEasy推送支持websocket 和polling两种连接方式,从而可以支持IE6及其以上的所有版本,同时还支持其它浏览器诸如Firefox, Chrome, Safari 等等.支 持不同的开发语言:   GoEasy推送提供了Restful API接口,无论你的后台程序用的是哪种语言都可以通过RestfulAPI来实现后台实时推送.

Python Websocket消息推送---GoEasy

Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送速度快,代码简单易懂上手快浏览器兼容性:GoEasy推送支持websocket 和polling两种连接方式,从而可以支持IE6及其以上的所有版本,同时还支持其它浏览器诸如Firefox, Chrome, Safari 等等.支 持不同的开发语言:   GoEasy推送提供了Restful API接口,无论你的后台程序用的是哪种语言都可以通过RestfulAPI来实现后台实时推送.

PHP Websocket消息推送---GoEasy

Goeasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送!个人感觉goeasy推送更稳定,推送速度快,代码简单易懂上手快浏览器兼容性:GoEasy推送支持websocket 和polling两种连接方式,从而可以支持IE6及其以上的所有版本,同时还支持其它浏览器诸如Firefox, Chrome, Safari 等等.支 持不同的开发语言:   GoEasy推送提供了Restful API接口,无论你的后台程序用的是哪种语言都可以通过RestfulAPI来实现后台实时推送.

基于SignalR的消息推送与二维码描登录实现

1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于SinglarR消息推送机制的扫描登录.本系统涉及到以下知识点:     SignalR:http://signalr.net/ 这官网,ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当