Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WebSocket慢速-Java和JavaScript_Javascript_Java_Bukkit - Fatal编程技术网

WebSocket慢速-Java和JavaScript

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

我正在处理一个minecraft插件的编码。 但是现在我有以下问题,我的websocket服务器响应非常慢

这是我的WebSocketClass(用于插件)

//套接字服务器类

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启动时启动我们的专用任务
我们需要在bukkit和Websocket服务器启动时启动任务,这样它就可以开始处理消息和发送数据。这在我们的
onEnable()
中很容易做到,代码如下:

新建MessageProcessor(messageQueue).runTaskAsynchronously(this)

  • 停止专用任务
我们需要确保在禁用插件时停止专用任务,以防止bukkit滥发错误“
此插件在重新加载时未正确关闭其异步任务。
”。这很容易做到,因为我们在上面为此设置了特殊条件

为此,我们将以下代码放入我们的
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
        }
    }
}