Spring Websocket 开发

Websocket Spring 搭建网页聊天

注册服务
package com.web.socket;

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;

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
		WebSocketConfigurer
{
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry)
	{
	    // 注册一个消息实现类
		registry.addHandler(systemWebSocketHandler(), "/websocket")
				.addInterceptors(new WebSocketHandshakeInterceptor());
	}

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

}

握手协议
package com.web.socket;

import java.util.Map;

import javax.servlet.http.HttpSession;

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;

/**
 * 握手协议处理,主要封装用户信息
* @author 高国藩
* @date 2015年8月14日 上午10:57:53
 */
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor
{
	@Override
	public void afterHandshake(ServerHttpRequest arg0, ServerHttpResponse arg1,
			WebSocketHandler arg2, Exception arg3)
	{
		System.out.println("enter the afterHandshake");
	}

	/**
	 * 握手协议,在握手之间即通话链接之前,无论成功与否都会执行
	 * @param handler 目标handler,此时就是本程序中的SystemWebSocketHandler.java,都是在WebSocketConfig.java中注册的
	 * @param attribute 数据存入,可以在WebSocketSession中取出
	 */
	@Override
	public boolean beforeHandshake(ServerHttpRequest request,
			ServerHttpResponse arg1, WebSocketHandler handler,
			Map<String, Object> attribute) throws Exception
	{
		System.out.println("enter the beforeHandshake");
		if(request instanceof ServerHttpRequest){
			ServletServerHttpRequest servletRequest=(ServletServerHttpRequest) request;
		  HttpSession session=servletRequest.getServletRequest().getSession(false);
		  if(session!=null){
			  String userName=(String) session.getAttribute(Constants.SESSION_USERNAME);
			  System.out.println("userName+++++++++++++"+userName);
			  // 这里不知道有什么用
		      attribute.put(Constants.WEBSOCKET_USERNAME, userName);
		  }
		}
		return true;
	}
}

发送消息
package com.web.socket;

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

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;

public class SystemWebSocketHandler implements WebSocketHandler
{

	// 创建一个集合存放websocketsession
	private static final ArrayList<WebSocketSession> users;

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

	//连接以创建以后执行的方法
	@Override
	public void afterConnectionEstablished(WebSocketSession session)
			throws Exception
	{
		users.add(session);
		String userName = (String) session.getAttributes().get(
				Constants.WEBSOCKET_USERNAME);
		System.out.println(userName+" 链接成功... ");
		if (userName != null)
		{
			// 查询未读消息
		}
	}
   //接收客户端发送过来的方法
	@Override
	public void handleMessage(WebSocketSession session,
			WebSocketMessage<?> message) throws Exception
	{
		String userName = (String) session.getAttributes().get(
				Constants.WEBSOCKET_USERNAME);
		System.out.print(userName+" 用户发送了消息:");
		System.out.println(message.getPayload().toString());
		TextMessage message1=new TextMessage(userName+" say "+"您好,您的消息已经收到了");
		 sendMessageToUsers(message1);
		 sendMessageToUser("高国藩", message1);
	}

	//传输错误时触发
	@Override
	public void handleTransportError(WebSocketSession session,
			Throwable exception) throws Exception
	{
		if (session.isOpen())
		{
			session.close();
		}
		users.remove(session);
	}

	//连接关闭时触发
	@Override
	public void afterConnectionClosed(WebSocketSession session,
			CloseStatus closeStatus) throws Exception
	{
		users.remove(session);
	}

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

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

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

config目录下的两个配置xml

core.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd">
</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:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:websocket="http://www.springframework.org/schema/websocket"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

<!-- 注解扫描包 -->
	<context:component-scan base-package="com.web" />
	<!-- 开启注解 -->

	<mvc:annotation-driven />

	<!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" 
		/> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean> -->
	<!-- 静态资源访问 -->
	<mvc:resources location="/img/" mapping="/img/**" />
	<mvc:resources location="/js/" mapping="/js/**" />


	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>

	<!-- <bean id="websocket" class="com.web.socket.SystemWebSocketHandler" />
	<websocket:handlers>
		<websocket:mapping path="/websocket" handler="websocket" />
		<websocket:handshake-interceptors>
			<bean class="com.web.socket.WebSocketHandshakeInterceptor" />
		</websocket:handshake-interceptors>
	</websocket:handlers> -->
</beans>

通信jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Testing websockets</title>
<script type="text/javascript" src="js/myUtil.js"></script>
<script type="text/javascript">
	var webSocket
	function initpage() {
		//创建socket对象
		webSocket = new WebSocket("ws://" + window.location.host
				+ "${pageContext.request.contextPath}/websocket");
		//为websocket连接服务器异常注册事件
		webSocket.onerror = function(event) {
			onError(event)
		};
		//为websocket连接到服务器时注册事件
		webSocket.onopen = function(event) {
			onOpen(event)
		};

		//为websocket注册消息处理事件
		webSocket.onmessage = function(event) {
			onMessage(event)
		};
	}
	//显示消息对话框
	function initWebSocket() {
		document.getElementById("dialog").style.display = "";
	}
	//处理从服务端发送过来的数据
	function onMessage(event) {
		alert("receive from service:" + event.data);
		var msgjson = JSON.parse(event.data);
		if (msgjson.sendMark == "1") {
			document.getElementById('showMsg').value = event.data;
			alert("json msg:" + msgjson.msg);
		} else {
			alert("消息发送失败");
		}
	}
	//连接打开时所做的处理
	function onOpen(event) {
		document.getElementById('showMsg').innerHTML = 'connected';
	}
	//连接异常时所做的处理
	function onError(event) {
		alert(event.data);
	}
	//向服务端推送消息
	function sendMessage() {
		var message = document.getElementById('msg').value;
		alert("message:" + message);
		var frommcn = document.getElementById('frommcn').value;
		alert("frommcn:" + frommcn);
		var tomcn = document.getElementById('tomcn').value;
		alert("tomcn:" + tomcn);
		//创建一个空的对象
		var msgjson = {};
		msgjson.frommcn = frommcn;
		msgjson.tomcn = tomcn;
		msgjson.msg = message;
		//将对象转换成json字符串
		var jsonstr = JSON.stringify(msgjson);
		alert("jsonstr:" + jsonstr);
		webSocket.send(jsonstr);
		var nowtime = dateformat();
		document.getElementById("showMsg").value += "<br/>" + nowtime;
		document.getElementById("showMsg").value += "<br/>" + message;
	}
</script>
</head>
<body οnlοad="initpage();">
	<a href="javascript:initWebSocket();">105015</a>
	<input type="hidden" value="101515" id="tomcn" />
	<input type="hidden" value="147258" id="frommcn" />
	<div id="messages"></div>
	<div style="width: 70%; text-align: right; margin: auto; display: none"
		id="dialog">
		<div>
			<table style="border: 1px solid black; margin: auto;">
				<tr>
					<td colspan="2"><textarea rows="10" cols="80" id="showMsg"
							style="overflow-y: scroll; resize: none"></textarea></td>
				</tr>
				<tr>
					<td colspan="2"><textarea id="msg" rows="3" cols="80"
							style="overflow-y: scroll; resize: none"></textarea></td>
				</tr>
				<tr>
					<td colspan="2"><input type="button" value="发送"
						style="width: 100%" οnclick="sendMessage();" /></td>
				</tr>
			</table>
		</div>
	</div>
</body>
</html>

项目结构




项目下载地址
http://download.csdn.net/detail/u014201191/9119159
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值