spring websocket demo

 

此demo在google浏览器下测试通过

 

  1. 首先websocket 的支持要分两部分
  2. 框架的支持 针对 spring框架
  3. 代码的支持 含有3部分代码
  4. nginx的配置文件也需要改造

pom.xml调整

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>

package com.dozenx.web.module.websocket;

import java.io.IOException;
import java.util.ArrayList;

import com.dozenx.web.core.Constants;
import com.dozenx.web.core.auth.session.SessionUser;
import org.apache.log4j.Logger;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class ChatMessageHandler extends TextWebSocketHandler {

    private static final ArrayList<WebSocketSession> users;// 这个会出现性能问题,最好用Map来存储,key用userid
    private static Logger logger = Logger.getLogger(ChatMessageHandler.class);

    static {
        users = new ArrayList<WebSocketSession>();
    }

    /**
     * 连接成功时候,会触发UI上onopen方法
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("connect to the websocket success......");
        users.add(session);
        // 这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户
        // TextMessage returnMessage = new TextMessage("你将收到的离线");
        // session.sendMessage(returnMessage);
    }

    /**
     * 在UI在用js调用websocket.send()时候,会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        SessionUser from =   (SessionUser)(session.getAttributes().get(Constants.SESSION_USER));
        String to ="大家";
       ;

        sendMessageToUsers(new TextMessage(from.getUserName()+"对 "+to+" 说:"+new String (message.asBytes())));
        //super.handleTextMessage(session, message);
    }

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

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

                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        logger.debug("websocket connection closed......");
        users.remove(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("websocket connection closed......");
        users.remove(session);
    }

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

}

 

package com.dozenx.web.module.websocket;

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.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @Author: dozen.zhang
 * @Description:
 * @Date: Created in 9:47 2018/10/30
 * @Modified By:
 */
@EnableWebMvc
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatMessageHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor());

        registry.addHandler(chatMessageHandler2(),"/webSocketServer2").addInterceptors(new WebSocketHandshakeInterceptor());


        registry.addHandler(chatMessageHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();
    }

    @Bean
    public TextWebSocketHandler chatMessageHandler(){
        return new ChatMessageHandler();
    }


    @Bean
    public TextWebSocketHandler chatMessageHandler2(){
        return new ChatMessageHandler2();
    }

}
package com.dozenx.web.module.websocket;

import com.dozenx.util.StringUtil;
import com.dozenx.web.core.Constants;
import com.dozenx.web.core.auth.session.SessionUser;
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.support.HttpSessionHandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * @Author: dozen.zhang
 * @Description:
 * @Date: Created in 9:48 2018/10/30
 * @Modified By:
 */
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        System.out.println("Before Handshake");
        String userName ="";
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest)request;
            HttpSession session = servletRequest.getServletRequest().getSession(true);
            if (session !=null) { //使用userName区分WebSocketHandler,以便定向发送消息
                 SessionUser sessionUser =
                (SessionUser) session.getAttribute(Constants.SESSION_USER);//这部分可以自己改造  用你自己的session对象 直接是一个用户名字符串也可以的 ^_^
                if(sessionUser == null) {
                    return false;

                }
                attributes.put(Constants.SESSION_USER, sessionUser);//标识用户已经登录

            }else{
                return false;
            }
        }

        //使用userName区分WebSocketHandler,以便定向发送消息(使用shiro获取session,或是使用上面的方式)
        //  String userName = (String) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER);
//        if (userName == null) {
//            userName = "default-system";
//        }
        attributes.put(Constants.SESSION_USER, StringUtil.getRandomString(5));

        boolean flag =  super.beforeHandshake(request, response, wsHandler, attributes);
        return flag;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception ex) {
        System.out.println("After Handshake");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
<!DOCTYPE html>
<html>
<head>
	<title>Web Socket Client</title>
</head>
<body style="padding:10px;">
	<h1>Web Socket Chating Room</h1>
	<div style="margin:5px 0px;">
		Address:
		<div><input id="address" type="text" value="/home/webSocketServer" style="width:400px;"/></div>
	</div>
	<div style="margin:5px 0px;">
		Name:
		<div><input id="name" type="text" value="Byron" style="width:400px;"/></div>
	</div>
	<div>
		<button id="connect" onclick="connect();">connect server</button> &nbsp;&nbsp;
		<button id="disconnect" onclick="quit();">disconnect</button>&nbsp;&nbsp;
		<button id="clear" onclick="clearMsg();">clear</button>

		<button id="team" onclick="team();">配对</button>
	</div>
	<h5 style="margin:4px 0px;">Message:</h5>
	<div id="message" style="border:solid 1px #333; padding:4px; width:400px; overflow:auto;
	 	background-color:#404040; height:300px; margin-bottom:8px; font-size:14px;">
	</div>
	<input id="text" type="text" onkeypress="enter(event);" style="width:340px"/> &nbsp;&nbsp;
	<button id="send" onclick="send();">send</button>

	<script type="text/javascript">




		var name=document.getElementById('name').value;
		var msgContainer=document.getElementById('message');
		var text=document.getElementById('text');
var ws;
		function connect () {
			var address="ws://" + document.location.host+document.getElementById('address').value;
			
			ws=new WebSocket(address);
			ws.onopen=function(e){
				var msg=document.createElement('div');
				msg.style.color='#0f0';
				msg.innerHTML="Server > connection open.";
				msgContainer.appendChild(msg);
				ws.send('{<'+document.getElementById('name').value+'>}');
			};
			ws.onmessage=function(e){
				var msg=document.createElement('div');
				msg.style.color='#fff';
				msg.innerHTML=e.data;
				msgContainer.appendChild(msg);
			};
			ws.onerror=function(e){
				var msg=document.createElement('div');
				msg.style.color='#0f0';
				msg.innerHTML='Server > '+e.data;
				msgContainer.appendChild(msg);
			};
			ws.onclose=function(e){
				var msg=document.createElement('div');
				msg.style.color='#0f0';
				msg.innerHTML="Server > connection closed by server.";
				msgContainer.appendChild(msg);
			};
			text.focus();
		}

		function quit(){
			if(ws){
				ws.close();
				var msg=document.createElement('div');
				msg.style.color='#0f0';
				msg.innerHTML='Server > connection closed.';
				msgContainer.appendChild(msg);
				ws=null;
			}
		}

		function send(){
			ws.send(text.value);
			setTimeout(function(){
				msgContainer.scrollTop=msgContainer.getBoundingClientRect().height;
			},100);
			text.value='';
			text.focus();
		}

		function clearMsg(){
			msgContainer.innerHTML="";
		}



		function enter(event){
			if(event.keyCode==13){
			 send(); 
			} 
		}
	</script>



</body>
</html>

 

 


http {
    include       mime.types;
    default_type  application/octet-stream;


#access_log  logs/access.log  main;

    sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
    keepalive_timeout  65;
# websocket
    upstream websocket {
        server 127.0.0.1:8081;
    }
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen       80;
        server_name  localhost;


#access_log  logs/host.access.log  main;

        location / {


        location  /home/webSocketServer {
            proxy_pass http://websocket;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For
                $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
        

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值