欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于spring实现websocket实时推送实例

程序员文章站 2023-11-27 11:22:46
基于spring框架来写的,websocket实时推送例子,具体内容如下 第一步:自己搭建一个springmvc项目,很简单,网上百度都有;pom文件添加以下:...

基于spring框架来写的,websocket实时推送例子,具体内容如下

第一步:自己搭建一个springmvc项目,很简单,网上百度都有;pom文件添加以下:

<!-- websocket --> 
 <dependency> 
 <groupid>org.springframework</groupid> 
 <artifactid>spring-websocket</artifactid> 
 <version>4.2.4.release</version> 
 </dependency> 
 
 
 <dependency> 
 <groupid>org.springframework</groupid> 
 <artifactid>spring-messaging</artifactid> 
 <version>4.2.4.release</version> 
 </dependency> 

我的spring版本是4.2.4的,所以websocket也是4.2.4的;websocket最好和spring版本保持一致

第二步:编写消息处理器

/** 
 * project name:springrabbitmq 
 * file name:mymessagehandler.java 
 * package name:com.zsy.websocket 
 * date:2018年1月31日上午11:10:03 
 * copyright (c) 2018, zhaoshouyun all rights reserved. 
 * 
 */ 
 
package com.zsy.websocket; 
 
import java.io.ioexception; 
import java.util.map; 
import java.util.set; 
import java.util.concurrent.concurrenthashmap; 
 
import org.apache.commons.lang3.stringutils; 
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; 
 
/** 
 * classname: mymessagehandler 
 * function: 实现webscoket接口 
 * date: 2018年1月31日 上午11:10:03 
 * @author zhaoshouyun 
 * @version 
 * @since jdk 1.7 
 */ 
public class mymessagehandler implements websockethandler { 
 //用户key 
 public static final string user_key = "current_user"; 
 
 /** 
 * usermap:存储用户连接webscoket信息 
 * @since jdk 1.7 
 */ 
 private final static map<string, websocketsession> usermap; 
 static { 
 usermap = new concurrenthashmap<string,websocketsession>(30); 
 } 
 /** 
 * 关闭websocket时调用该方法 
 * @see org.springframework.web.socket.websockethandler#afterconnectionclosed(org.springframework.web.socket.websocketsession, org.springframework.web.socket.closestatus) 
 */ 
 @override 
 public void afterconnectionclosed(websocketsession session, closestatus status) throws exception { 
  string userid = this.getuserid(session); 
  if(stringutils.isnoneblank(userid)){ 
  usermap.remove(userid); 
  system.err.println("该" + userid +"用户已成功关闭"); 
  }else{ 
  system.err.println("关闭时,获取用户id为空"); 
  } 
 
 } 
 
 /** 
 * 建立websocket连接时调用该方法 
 * @see org.springframework.web.socket.websockethandler#afterconnectionestablished(org.springframework.web.socket.websocketsession) 
 */ 
 @override 
 public void afterconnectionestablished(websocketsession session) throws exception { 
 string userid = this.getuserid(session); 
 if(stringutils.isnoneblank(userid)){ 
  usermap.put(userid, session); 
  session.sendmessage(new textmessage("建立websocket连接成功!")); 
 } 
 
 } 
 
 /** 
 * 客户端调用websocket.send时候,会调用该方法,进行数据通信 
 * @see org.springframework.web.socket.websockethandler#handlemessage(org.springframework.web.socket.websocketsession, org.springframework.web.socket.websocketmessage) 
 */ 
 @override 
 public void handlemessage(websocketsession session, websocketmessage<?> message) throws exception { 
  string msg = message.tostring(); 
  string userid = this.getuserid(session); 
  system.err.println("该"+userid+"用户发送的消息是:"+msg); 
  message = new textmessage("服务端已经接收到消息,msg="+msg); 
  session.sendmessage(message); 
 
 } 
 
 /** 
 * 传输过程出现异常时,调用该方法 
 * @see org.springframework.web.socket.websockethandler#handletransporterror(org.springframework.web.socket.websocketsession, java.lang.throwable) 
 */ 
 @override 
 public void handletransporterror(websocketsession session, throwable e) throws exception { 
 websocketmessage<string> message = new textmessage("异常信息:"+e.getmessage()); 
 session.sendmessage(message); 
 } 
 
 /** 
 * 
 * @see org.springframework.web.socket.websockethandler#supportspartialmessages() 
 */ 
 @override 
 public boolean supportspartialmessages() { 
 
 return false; 
 } 
 
 /** 
 * sendmessagetouser:发给指定用户 
 * @author zhaoshouyun 
 * @param userid 
 * @param contents 
 * @since jdk 1.7 
 */ 
 public void sendmessagetouser(string userid,string contents) { 
 websocketsession session = usermap.get(userid); 
 if(session !=null && session.isopen()) { 
  try { 
    textmessage message = new textmessage(contents); 
  session.sendmessage(message); 
  } catch (ioexception e) { 
  e.printstacktrace(); 
  } 
 } 
 } 
 
 /** 
 * sendmessagetoallusers:发给所有的用户 
 * @author zhaoshouyun 
 * @param contents 
 * @since jdk 1.7 
 */ 
 public void sendmessagetoallusers(string contents) { 
  set<string> userids = usermap.keyset(); 
  for(string userid: userids) { 
  this.sendmessagetouser(userid, contents); 
  } 
 } 
 
 /** 
 * getuserid:获取用户id 
 * @author zhaoshouyun 
 * @param session 
 * @return 
 * @since jdk 1.7 
 */ 
 private string getuserid(websocketsession session){ 
 try { 
  string userid = (string)session.getattributes().get(user_key); 
  return userid; 
 } catch (exception e) { 
  e.printstacktrace(); 
 } 
 return null; 
 } 
 
}

 第三步:编写websocket相关配置,当然可以在xml配置;我现在没有使用xml配置,使用代码配置,需要在xml里添加扫描包<context:component-scan base-package="com.zsy.websocket" />

 

/** 
 * project name:springrabbitmq 
 * file name:websocketconfig.java 
 * package name:com.zsy.websocket 
 * date:2018年1月31日下午1:10:33 
 * copyright (c) 2018, zhaoshouyun all rights reserved. 
 * 
*/ 
/** 
 * project name:springrabbitmq 
 * file name:websocketconfig.java 
 * package name:com.zsy.websocket 
 * date:2018年1月31日下午1:10:33 
 * copyright (c) 2018, zhaoshouyun all rights reserved. 
 * 
 */ 
 
package com.zsy.websocket; 
 
import org.springframework.context.annotation.bean; 
import org.springframework.context.annotation.configuration; 
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; 
 
/** 
 * classname: websocketconfig 
 * function: todo add function. 
 * date: 2018年1月31日 下午1:10:33 
 * @author zhaoshouyun 
 * @version 
 * @since jdk 1.7 
 */ 
@configuration 
@enablewebsocket 
public class websocketconfig implements websocketconfigurer { 
 
 /** 
 * 注册handle 
 * @see org.springframework.web.socket.config.annotation.websocketconfigurer#registerwebsockethandlers(org.springframework.web.socket.config.annotation.websockethandlerregistry) 
 */ 
 @override 
 public void registerwebsockethandlers(websockethandlerregistry registry) { 
  registry.addhandler(myhandler(), "/testhandler").addinterceptors(new websocketinterceptor()); 
  registry.addhandler(myhandler(), "/socketjs/testhandler").addinterceptors(new websocketinterceptor()).withsockjs(); 
 
 } 
 
 @bean 
 public websockethandler myhandler(){ 
 return new mymessagehandler(); 
 } 
 
} 

第四步:编写websocket适配器

package com.zsy.websocket; 
 
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.support.httpsessionhandshakeinterceptor; 
 
/** 
 * classname: websocketinterceptor 
 * function: todo add function. 
 * date: 2018年1月31日 上午11:42:34 
 * @author zhaoshouyun 
 * @version 
 * @since jdk 1.7 
 */ 
public class websocketinterceptor extends httpsessionhandshakeinterceptor { 
 /** 
 * todo 简单描述该方法的实现功能(可选). 
 * @see org.springframework.web.socket.server.support.httpsessionhandshakeinterceptor#beforehandshake(org.springframework.http.server.serverhttprequest, org.springframework.http.server.serverhttpresponse, org.springframework.web.socket.websockethandler, java.util.map) 
 */ 
 @override 
 public boolean beforehandshake(serverhttprequest request, serverhttpresponse response, websockethandler wshandler, 
  map<string, object> attributes) throws exception { 
 if(request instanceof servletserverhttprequest){ 
  servletserverhttprequest serverhttprequest = (servletserverhttprequest)request; 
  //获取参数 
  string userid = serverhttprequest .getservletrequest().getparameter("userid"); 
  attributes.put(mymessagehandler.user_key, userid); 
 } 
  
 return true; 
 } 
} 

第五步对应的js:

<%@ page language="java" contenttype="text/html; charset=iso-8859-1" 
 pageencoding="iso-8859-1"%> 
<!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> 
<title>insert title here</title> 
<script type="text/javascript"> 
 
var websocket; 
 
// 首先判断是否 支持 websocket 
 if('websocket' in window) { 
 websocket = new websocket("ws://localhost:8085/springtest/testhandler?userid=zhaoshouyun"); 
 } else if('mozwebsocket' in window) { 
 websocket = new mozwebsocket("ws://localhost:8085/springtest/testhandler?userid=zhaoshouyun"); 
 } else { 
 websocket = new sockjs("http://localhost:8085/springtest/socketjs/testhandler?userid=zhaoshouyun"); 
 } 
 
 // 打开连接时 
 websocket.onopen = function(evnt) { 
 console.log(" websocket.onopen "); 
 }; 
 
 // 收到消息时 
 websocket.onmessage = function(evnt) { 
 alert(evnt.data); 
 }; 
 
 websocket.onerror = function(evnt) { 
 console.log(" websocket.onerror "); 
 }; 
 
 websocket.onclose = function(evnt) { 
 console.log(" websocket.onclose "); 
 }; 
 
 
function say(){ 
 //客户端主动发消息 
 websocket.send(document.getelementbyid('msg').value); 
} 
 
</script> 
</head> 
<body> 
<input type="text" value="" id="msg"><button onclick="say()"></button> 
</body> 
</html> 

第六步测试:

package com.zsy.test.controller; 
 
import java.util.hashmap; 
import java.util.map; 
 
import org.springframework.beans.factory.annotation.autowired; 
import org.springframework.beans.factory.annotation.value; 
import org.springframework.stereotype.controller; 
import org.springframework.web.bind.annotation.requestbody; 
import org.springframework.web.bind.annotation.requestmapping; 
import org.springframework.web.bind.annotation.responsebody; 
 
import com.zsy.websocket.mymessagehandler; 
 
/** 
 * classname: testcontroller 
 * function: todo add function. 
 * date: 2017年12月14日 上午11:11:23 
 * @author zhaoshouyun 
 * @version 
 * @since jdk 1.7 
 */ 
@controller 
public class testcontroller { 
 
 
 
 @autowired 
 mymessagehandler handler; 
  
 @requestmapping("/get") 
 public string get(){ 
 return "index"; 
 } 
 
 @responsebody 
 @requestmapping("/get1") 
 public string send(string name){ 
 handler.sendmessagetouser("zhaoshouyun", "服务端发送的内容:"+name); 
 return "success"; 
 } 
 
 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。