websocket(带session传输数据)

maven导入一个包即可

<dependency>

            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>

</dependency>


注意:tomcat版本最好是8.0,原来用的7.0版本建立不了链接


简单的发送消息的页面

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
 <script type="text/javascript" src="js/c.js"></script>
 
</head>
<body >
	
<div>
    <p>
        <input type="text" placeholder="type and press enter to chat" id="chat" />
    </p>
    <input type="button" value="send" class="btn" id="send">
    <div id="console-container">
        <div id="console"></div>
    </div>
</div>

</body>
</html>

c.js封装了websock的连接:

var Chat = {};
Chat.socket = null;
Chat.connect = (function(host) {
	//创建webSocket,
	if ('WebSocket' in window) {
		Chat.socket = new WebSocket(host);
	} else if ('MozWebSocket' in window) {
		Chat.socket = new MozWebSocket(host);
	} else {
		//Console.log('Error: WebSocket is not supported by this browser.');
		// return;
		Chat.socket = new SockJS(
				"http://localhost:8080/websocket5/sockjs/webSocketServer");
	}
	//建立websocket的事件,可以用来做一些初始化操作
	Chat.socket.onopen = function() {
		$("#send").click(function(){
			Chat.sendMessage();
		});	
	};
	//绑定关闭事件   
	Chat.socket.onclose = function() {
		document.getElementById('chat').onkeydown = null;
	};
	//监听消息
	Chat.socket.onmessage = function(message) {
		Console.log(message.data);
	};
	//出现错误的时候的方法  
	Chat.socket.onerror =function(event){  
    }; 
});

Chat.initialize = function() {
	if (window.location.protocol == 'http:') {
		Chat.connect('ws://' + window.location.host + '/websocket5/chat');
	} else {
		Chat.connect('ws://' + window.location.host + '/websocket5/chat');
	}
};
//发送消息的方法
Chat.sendMessage = (function() {
	var message = document.getElementById('chat').value;
	if (message != '') {
		Chat.socket.send(message);
		document.getElementById('chat').value = '';
	}
});

var Console = {};
//打印消息的方法 
Console.log = (function(message) {
	var console = document.getElementById('console');
	var p = document.createElement('p');
	p.style.wordWrap = 'break-word';
	p.innerHTML = message;
	console.appendChild(p);
	while (console.childNodes.length > 25) {
		console.removeChild(console.firstChild);
	}
	console.scrollTop = console.scrollHeight;
});

Chat.initialize();

js中会扫描服务器中的/chat

package com.yc.web.websocket;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.yc.web.model.GetHttpSessionConfigurator;

@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfigurator.class)
public class WebSocket {

	private static final String GUEST_PREFIX = "Guest";
	private static final AtomicInteger connectionIds = new AtomicInteger(0);
	private static final Set<WebSocket> connections = new CopyOnWriteArraySet<>();

	private final String nickname;
	private Session session;
	private static HttpSession httpSession;

	public WebSocket() {
		nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
	}

	@OnOpen
	public void start(Session session, EndpointConfig config) {
		this.session = session;
		httpSession = (HttpSession) config.getUserProperties().get(
				HttpSession.class.getName());
		connections.add(this);
		System.out.println(httpSession.getAttribute("name"));
		String message = String.format("* %s %s", nickname, "has joined.");
		broadcast(message);
	}

	@OnClose
	public void end() {
		connections.remove(this);
		String message = String
				.format("* %s %s", nickname, "has disconnected.");
		broadcast(message);
	}

	// 监听要发送的内容
	@OnMessage
	public void incoming(String message) {
		// Never trust the client
		// TODO: 过滤输入的内容
		broadcast(message);
	}

	@OnError
	public void onError(Throwable t) throws Throwable {
		System.out.println("Chat Error: " + t.toString());
	}

	private static void broadcast(String msg) {
		for (WebSocket client : connections) {
			try {
				synchronized (client) {
					client.session.getBasicRemote().sendText(msg);
				}
			} catch (IOException e) {
				System.out
						.println("Chat Error: Failed to send message to client");
				connections.remove(client);
				try {
					client.session.close();
				} catch (IOException e1) {
				}
				String message = String.format("* %s %s", client.nickname,
						"has been disconnected.");
				broadcast(message);
			}
		}
	}
}

注意
@ServerEndpoint中
如果配置了
configurator = GetHttpSessionConfigurator.class

就必须保证session中是有值的,不然就无法建立websocket链接且报空指针错误

GetHttpSessionConfigurator.class:

package com.yc.web.model;

import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.Session;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.yc.web.actions.User;

//配置类  将http中的session传入websocket中
public class GetHttpSessionConfigurator extends
		ServerEndpointConfig.Configurator {
	@Override
	public void modifyHandshake(ServerEndpointConfig config,
			HandshakeRequest request, HandshakeResponse response) {
		// TODO Auto-generated method stub
		HttpSession httpSession = (HttpSession) request.getHttpSession();
		// ActionContext.getContext().getSession()
		config.getUserProperties().put(HttpSession.class.getName(), httpSession);
	}
}

加这个配置是为了让session中的值传入到websocket中


为了存入session,简单的写个登录界面

<!DOCTYPE html>
<html>
<head>
<title>login.html</title>
</head>

<body>
	<form action="file.action" method="post">
		姓名:<input type="text" name="name" /> <input type="submit">
	</form>
</body>
</html>
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	
	
	<servlet>    
      <servlet-name>wsServlet</servlet-name>    
      <servlet-class>com.yc.web.li.LoginServlet</servlet-class>    
  </servlet>    
  <servlet-mapping>    
      <servlet-name>wsServlet</servlet-name>    
      <url-pattern>*.action</url-pattern>    
  </servlet-mapping>  
</web-app>

注意扫描的时候不要扫描/  因为用了/  就会把websocket的/chat也拦截了


LoginServlet.class

package com.yc.web.li;

import java.io.IOException;  
import java.io.PrintWriter;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
/** 
 * 处理用户的登陆. 
 * @author nagsh 
 * 
 */  
public class LoginServlet extends HttpServlet {  
  
      
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doPost(request, response);  
    }  
  
      
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
  
        response.setContentType("text/html");  
        PrintWriter out = response.getWriter();  
          
        String name = request.getParameter("name");  
        //将当前用户的信息存入session中  
        request.getSession().setAttribute("name",name);  
        //重定向到聊天界面  
        response.sendRedirect("/websocket5/index.html");  
    }  
  
} 

这只是单独的弄了个小例子,整合进项目注意事项还多

websocket发送过程:点击客户端send发送按钮-》进入Chat.socket.onopen调用Chat.sendMessage()-》Chat.sendMessage()中的Chat.socket.send(message);-》进入服务器端@OnMessage调用broadcast(message);进行发送

websocket接收过程:客户端的Chat.socket.onmessage直接进行监听,调用Console.log(message.data);进行显示

详细项目 https://github.com/937129397/microBlog/tree/dev/microBlog




版权声明:本文为z719725611原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。