我有一个奇怪的情况,我需要从我的主流程中创建许多流程。
我创建的这些进程会将来自网络套接字的某些消息排队。
然后每隔一段时间(大约每秒),我将从主进程中轮询这些小进程。我使用的语言是D,消息传递库是ZMQD(这只是C zmq库的包装器)。
我为主要流程准备的最小示例:
Socket*[] socketList;
string sRecv( Socket* socket)
{
ubyte[256] buffer;
immutable size = socket.receive(buffer);
import std.algorithm: min;
return buffer[0 .. min(size,256)].idup.asString();
}
void startServer( string servername )
{
auto pid = spawnProcess(["/home/erdem/eclipse-workspace/WebSocketDenemesi/websocketdenemesi",
servername, "\n"]);
auto requester = new Socket(SocketType.req);
auto allName = "ipc:///tmp/" ~ servername;
requester.connect(allName);
socketList ~= requester;
}
void main() {
import std.array : split;
import std.algorithm : each;
startServer("iotabtc@depth");
startServer("iotabtc@aggTrade");
startServer("ethbtc@depth");
int counter = 30;
while(counter--) {
foreach ( requester; socketList)
{
requester.send("send");
}
foreach ( requester; socketList)
{
auto strList = sRecv(requester).split("\n");
strList.each!( str => writefln("Received [%d]reply [%s]", strList.length, str) );
}
sleep(1000.msecs);
}
foreach ( requester; socketList)
{
requester.send("done");
}
}
还有我的小流程的最小示例:
WebSocket startSocket( string temp )
{
auto ws_url = URL(temp);
auto ws = connectWebSocket(ws_url);
if ( !ws.connected )
return null;
return ws;
}
void close( WebSocket ws )
{
int timeOut = 5;
while ( ws && ws.connected && timeOut-- )
{
vibe.core.concurrency.async( { ws.close(); return true;} );
sleep(5.msecs);
}
}
string sRecv(ref Socket socket)
{
ubyte[256] buffer;
immutable size = socket.tryReceive(buffer)[0];
import std.algorithm: min;
return size ? buffer[0 .. min(size,256)].idup.asString() : "";
}
void main( string[] args ) {
auto responder = Socket(SocketType.rep);
string seperatorChar = args[2];
string temp = "ipc:///tmp/" ~ args[1];
responder.bind(temp);
string socketName = "wss://stream.binance.com:9443/ws/" ~ args[1];
auto curSocket = startSocket(socketName);
string curString;
while (true) {
auto result = responder.sRecv();
if ( result == "send")
{
responder.send(curString);
curString = "";
}
else if ( result == "done" )
{
break;
}
else
{
if ( curSocket.dataAvailableForRead )
{
auto text = curSocket.receiveText();
if ( !curString.empty )
curString ~= seperatorChar;
curString ~= text;
}
}
sleep(100.msecs);
}
writeln( "Shutting down: ", args[1]);
curSocket.close();
}
这是我第一次使用此消息传递库。这就是为什么我使用简单的 REQ/REP
套接字的原因。有没有更好的方法可以达到我的要求。例如,是否有更好的消息传递模式?例如,存在一种模式,其中我的小进程不会被 responder.receive( buffer );
阻塞。
如果有的话,那么我将不需要从另一个线程监听websocket。
答案 0 :(得分:1)
欢迎使用基于ZeroMQ的distributed-computing
例如,是否存在更好的消息传递模式?
这取决于您的流程如何进行通信。简而言之,在菜单模式下使用 REQ/REP
几乎是菜单中最糟糕的选择。
鉴于您的网络套接字仅收到一条异步信息(这是一种常见方式,即Markets如何重新广播事件流),即纯ws.recv()
+ PUSHer.send()
+ {{ 1}}流水线事件获取+ if PULLer.poll(): PULLer.recv()
传播+有条件的重新处理将最好地满足实际行为。
对于非本地节点,给您的处理场足迹可能超出单个本地主机和其他传输类,而PUSH/PULL
可能与{ tipc:// | tcp:// | udp:// | pgm:// | epgm:// | norm:// | vmci:// }
链接一起进入游戏在您当前的本地主机上-ZeroMQ在处理这种混合时的透明性是迁移到掌握Zen-of-Zero的一个不错的好处。
给定的延迟对于大规模的处理分布至关重要, ipc://
可扩展的正式通信原型模式可能会变得有益,可以选择使用PUB/SUB
对于非日志记录节点,只有最新价格与采取任何形式的任何响应性XTO操作有关。