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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章