WebSocket慢速-Java和JavaScript
我正在处理一个minecraft插件的编码。 但是现在我有以下问题,我的websocket服务器响应非常慢 这是我的WebSocketClass(用于插件) //套接字服务器类WebSocket慢速-Java和JavaScript,javascript,java,bukkit,Javascript,Java,Bukkit,我正在处理一个minecraft插件的编码。 但是现在我有以下问题,我的websocket服务器响应非常慢 这是我的WebSocketClass(用于插件) //套接字服务器类 package me.mickerd.pcoc; import java.io.IOException; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Collection; impo
package me.mickerd.pcoc;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import org.bukkit.Bukkit;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class WebsocketServer extends WebSocketServer {
public static WebsocketServer s;
public WebsocketServer(int port) throws UnknownHostException {
super(new InetSocketAddress(port));
}
public WebsocketServer(InetSocketAddress address) {
super(address);
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
WebsocketSessionManager.getSessionManager().openSession(conn.getRemoteSocketAddress().getAddress().getHostAddress());
Bukkit.getLogger().info(conn.getRemoteSocketAddress().getAddress().getHostName() + " has connected to the Websocket server!");
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
WebsocketSessionManager.getSessionManager().endSession(conn.getRemoteSocketAddress().getAddress().getHostAddress());
Bukkit.getLogger().info(conn + " has disconnected form the Websocket server");
}
@Override
public void onMessage(WebSocket conn, String message) {
Bukkit.getLogger().info("Recieve Websocket packet - " + conn + ":" + message);
if (message.split(":")[0].equalsIgnoreCase("name")) {
WebsocketSessionManager.getSessionManager().addSessionUsername(conn.getRemoteSocketAddress().getAddress().getHostAddress(), message.split(":")[1]);
}
}
public static void runServer() throws InterruptedException, IOException {
WebSocketImpl.DEBUG = true;
int port = 8887;
s = new WebsocketServer(port);
s.start();
Bukkit.getLogger().info("Websocket server started on port: " + s.getPort());
}
@Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
if (conn != null) {
// some errors like port binding failed may not be assignable to a specific websocket
}
}
public void sendToAll(String data) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
c.send(data);
}
}
}
public void sendData(WebsocketSession session, String data) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
if (c.getRemoteSocketAddress().getAddress().getHostAddress().equalsIgnoreCase(session.getHost())) {
Bukkit.getLogger().info("Send data packet: " + data);
c.send(data);
}
}
}
}
}
服务器的反应非常慢,但服务器上的其他东西速度惊人
有人能帮忙吗?您正在使用的websocket库发送数据阻塞,这意味着对
c.send(
的调用将阻塞,直到发送帧为止
有不同的方法可以解决这个问题,例如:
对每条消息使用单独的异步线程:
上面的类有两个特殊条件,next.getFirst()==null
和catch(InterruptedException e)
,当我们禁用插件退出任务时将使用这些条件
- 在bukkit启动时启动我们的专用任务
onEnable()
中很容易做到,代码如下:
新建MessageProcessor(messageQueue).runTaskAsynchronously(this)
- 停止专用任务
此插件在重新加载时未正确关闭其异步任务。
”。这很容易做到,因为我们在上面为此设置了特殊条件
为此,我们将以下代码放入我们的onDisable()
:
- 重写我们的方法以使用messageQueue
sendToAll
方法来使用我们的队列
public void sendToAll(String data) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
messageQueue.add(new Pair<>(c,data)); // Ferrybig: Use messageQueue
}
}
}
public void sendToAll(字符串数据){
集合con=连接();
已同步(con){
用于(WebSocket c:con){
messageQueue.add(新对(c,数据));//Ferrybig:使用messageQueue
}
}
}
同样的小修改也可以对sendData
方法进行,但我并没有把它作为读者的练习
旁注
BlockingQueue
的设计考虑了并发操作,不需要外部同步
您可以选择使用而不是BlockingQueue.add()
,因为后者在列表已满时引发异常,但第一个返回false
LinkedBlockingDeque
的默认大小是,并且可以用其更改。您的internet连接速度是多少?使用Wireshark查看哪部分通信速度慢,然后报告。
public void sendToAll(String data) {
// Ferrybig - added bukkit async task
Bukkit.getSchedular().runTaskAsynchronously(plugin, new Runnable(){
@Override public void run(){
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
c.send(data);
}
}
// Ferrybig - added bukkit async task
}});
}
private final BlockingQueue<Pair<WebSocket,String>> messageQueue
= new LinkedBlockingDeque<>();
public class MessageProcessor extends BukkitRunnable {
private BlockingQueue<Pair<WebSocket,String>> messageQueue;
public MessageProcessor (BlockingQueue<Pair<WebSocket,String>> messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
try {
Pair<WebSocket,String> next;
while(true) {
next = messageQueue.take();
if(next.getFirst() == null) {
// Special condition, will be explained later
return; // Quit run method
}
// System.out.println("Send message to " + next.getFirst()); // DEBUG
next.getFirst().send(next.getSecond());
}
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
// Someone wanted to quit our thread, so we are quiting
} finally {
messageQueue.clear();
}
}
}
public void sendToAll(String data) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
messageQueue.add(new Pair<>(c,data)); // Ferrybig: Use messageQueue
}
}
}