背景:做项目的时候有过这样的一个需求,在访问某个网页的时候进行登录,需要浏览器获取电脑的硬件资源,但是通过浏览器直接读取的方式有些不便,所以想到使用Java开发一个图形应用界面的程序读取电脑程序通过socket通信传输给html页面用于验证。
写在前面:在Java服务器这端开发中,使用到一个jar包,Java-WebSocket-1.3.0.jar,首先引入这个包,这个核心包就是用来复制Java进行WebSocket服务器的。
步骤1. 然后开始服务端编码,创建核心服务类WsServer
import java.net.InetSocketAddress;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class WsServer extends WebSocketServer {
public WsServer(int port) {
super(new InetSocketAddress(port));
}
public WsServer(InetSocketAddress address) {
super(address);
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
// ws连接的时候触发的代码,onOpen中我们不做任何操作
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
//断开连接时候触发代码
userLeave(conn);
System.out.println(reason);
}
@Override
public void onMessage(WebSocket conn, String message) {
String msg = "收到信息:"+message;
System.out.println(msg);
userJoin(conn,message);//用户加入
WsUtil.sendMessageToUser(conn,msg);
}
@Override
public void onError(WebSocket conn, Exception ex) {
//错误时候触发的代码
System.out.println("on error");
ex.printStackTrace();
}
/**
* 去除掉失效的websocket链接
* @param conn
*/
private void userLeave(WebSocket conn){
WsUtil.removeUser(conn);
}
/**
* 将websocket加入用户池
* @param conn
* @param userName
*/
private void userJoin(WebSocket conn,String userName){
WsUtil.addUser(userName, conn);
}
}
步骤2. 里面用到了工具类WsUtil,代码如下:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.java_websocket.WebSocket;
public class WsUtil {
private static final Map<WebSocket, String> wsUserMap = new HashMap<WebSocket, String>();
/**
* 通过websocket连接获取其对应的用户
*
* @param conn
* @return
*/
public static String getUserByWs(WebSocket conn) {
return wsUserMap.get(conn);
}
/**
* 根据userName获取WebSocket,这是一个list,此处取第一个
* 因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了)
*
* @param user
*/
public static WebSocket getWsByUser(String userName) {
Set<WebSocket> keySet = wsUserMap.keySet();
synchronized (keySet) {
for (WebSocket conn : keySet) {
String cuser = wsUserMap.get(conn);
if (cuser.equals(userName)) {
return conn;
}
}
}
return null;
}
/**
* 向连接池中添加连接
*
* @param inbound
*/
public static void addUser(String userName, WebSocket conn) {
wsUserMap.put(conn, userName); // 添加连接
}
/**
* 获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组
*
* @return
*/
public static Collection<String> getOnlineUser() {
List<String> setUsers = new ArrayList<String>();
Collection<String> setUser = wsUserMap.values();
for (String u : setUser) {
setUsers.add(u);
}
return setUsers;
}
/**
* 移除连接池中的连接
*
* @param inbound
*/
public static boolean removeUser(WebSocket conn) {
if (wsUserMap.containsKey(conn)) {
wsUserMap.remove(conn); // 移除连接
return true;
} else {
return false;
}
}
/**
* 向特定的用户发送数据
*
* @param user
* @param message
*/
public static void sendMessageToUser(WebSocket conn, String message) {
if (null != conn && null != wsUserMap.get(conn)) {
conn.send(message);
}
}
/**
* 向所有的用户发送消息
*
* @param message
*/
public static void sendMessageToAll(String message) {
Set<WebSocket> keySet = wsUserMap.keySet();
synchronized (keySet) {
for (WebSocket conn : keySet) {
String user = wsUserMap.get(conn);
if (user != null) {
conn.send(message);
}
}
}
}
}
步骤3. 最后在Main类中开启主服务:
import org.java_websocket.WebSocketImpl;
public class Main {
public static void main(String[] args) {
WebSocketImpl.DEBUG = false;
int port = 9090; // 端口
WsServer s = new WsServer(port);//实例化一个监听服务器
s.start();//启动服务器
}
}
步骤4. 点击运行按钮就可以在9090端口开启该服务,接下来进行HTML的编码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket</title>
</head>
<body>
<script>
var socket;
function connectServer(){
var socket_ip="127.0.0.1";
socket= new WebSocket('ws://'+socket_ip+':9090');
socket.onopen = function(event)
{
console.log("连接服务成功!");
sendMsg()
};
// 监听消息
socket.onmessage = function(event)
{
console.log('Client received a message',event);
console.log(event.data);
};
// 监听Socket的关闭
socket.onclose = function(event)
{
};
socket.onerror = function(event) {
//alert('无法连接到:' + socket_ip);
};
}
connectServer()
function sendMsg(){
socket.send("你好!");
}
</script>
</body>
</html>
结果展示:html连接上Java服务程序后并发送“你好”字样,Java收到后并给与了回复