我通过服务器将数据从客户端发送到客户端有一点问题(避免在客户端上侦听端口)。
我有这样的服务器:
var net = require("net");
var server = net.createServer(function(socket) {
socket.on("data", function(data) {
});
});
server.listen(port);
现在我想通过服务器将数据从一个客户端重定向到另一个客户端。但我不知道如何做到这一点,因为我不知道如何从另一个连接中解决连接问题。
有谁知道,我怎么能这样做?
答案 0 :(得分:0)
您可以将所有客户端保存在一个简单的数组中,并将其发送到每个客户端,而无需客户端的套接字ID。所以每个客户只会获得所有其他客户。然后你可以通过客户端ID来解决它:
var net = require("net");
var clients = {};
var server = net.createServer(function(socket) {
socket.on("connect", function ()
{
// Get the socket id of the connected client
var socketId = null;
// Get the client socket
var clientSocket = null;
clients[socketId] = clientSocket;
});
// Socket is the client
socket.on("data", function(data) {
var d = JSON.parse(data);
if (d.client)
{
if (!clients[d.client.id])
{
// Client doesn't exists
return;
}
// Send messages to the client with the saved socket
clients[d.client.id].send(d.data);
}
});
socket.on("end", function ()
{
// Get the socket id of the disconnected client
var socketId = null;
delete clients[socketId];
});
});
server.listen(port);
我知道与socket.io合作,我强烈建议你也可以使用它。
在socket.io中,它可能看起来像这样:
var io = require('socket.io')(80);
// Store all your clients
var clients = {};
// Example: http://socket.io/docs/#using-with-node-http-server
io.on("connection", function (socket)
{
// Save the client to let other client use it
clients[socket.id] = socket;
// Send all the clients except the self client
sendClient(socket);
// Client disconnected or connection somehow lost
socket.on("disconnect", function ()
{
// Remove the client
delete clients[socket.id];
});
// Simple event to proxy to another client
socket.on("proxy", function (client)
{
if (clients[client.id])
clients[client.id].emit("event", client.data);
});
});
// Send all the clients and exclude the given socket id
function sendClient(socket)
{
var list = [];
for (let socketId in clients)
{
if (!clients.hasOwnProperty(socketId))
continue;
if (socketId == socket.id)
continue;
list.push(socketId);
}
socket.emit("clients", list);
}
,客户端可以(使用socket-io.client):
var io = require('socket.io-client');
var socket = io("http://localhost:80");
socket.on("connect", function ()
{
});
socket.on("clients", function (clients)
{
// We have all the clients
clients.forEach(function (clientId)
{
var client = {};
client.id = clientId;
client.data = {blah: 1};
socket.emit("proxy", client);
});
});
socket.on("disconnect", function ()
{
});
答案 1 :(得分:0)
您必须将连接存储在某个位置,例如在数组中(如果您有两个以上)或键入某种唯一标识符的对象,您可以使用它来轻松查找目标套接字。例如:
group by
如果你的应用需要更灵活,你可以使它更复杂。例如,您可以通过在连接时从源套接字读取一行(由<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/scrollView" >
<include android:layout_height="match_parent"
android:layout_width="match_parent"
layout="@layout/your_current_layout_for_profile_without_list_view" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView" />
</ScrollView>
终止)来找到目标套接字,其中包含目标套接字的IP地址。然后,您可以在每个套接字的IP地址上键入一个对象,而不是数组,这样您就可以轻松找到合适的目标套接字。
或者你可能每个源套接字都发送一个&#34;用户ID&#34;和请求的目的地&#34;用户ID。&#34;此时,您可以将初始单行设为JSON字符串,后跟<ScrollView
android:id="@+id/scrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="1dp"
android:layout_height="40dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="20dp"
android:layout_marginTop="4dp"
android:background="#c0c0c0" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:src="@drawable/touch" />
<TextView
android:id="@+id/mynumofposts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="200"
android:textStyle="bold" />
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="40dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="25dp"
android:layout_marginTop="4dp"
android:background="#c0c0c0" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:src="@drawable/nearbycircle" />
<TextView
android:id="@+id/mynumoffollowers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="300"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myprofilelist"/>
</ScrollView>
,这样客户端就可以发送任意数量的参数来实现桥接。
使用JSON标头的更复杂解决方案的示例:
var sockets = [];
net.createServer(function(s) {
// Add the socket to our connected socket list
sockets.push(s);
// Automatically remove the socket when it disconnects
s.on('close', function() {
sockets.splice(sockets.indexOf(s), 1);
});
// How you determine the destination socket is up to you
var destSocket = ...;
// This pipes data between the current socket and the
// destination socket (both directions) but does not automatically
// close one socket when the other socket closes
s.pipe(destSocket, { end: false })
.pipe(s, { end: false });
}).listen(port);
上述解决方案的示例客户端:
\n
此客户端连接后(假设已标识为\n
的另一个套接字已连接),目标套接字应该看到数据var sockets = Object.create(null);
net.createServer(function(s) {
s.on('error', function(err) {
});
readJSON(s, function(err, result) {
var dest;
// Check if socket closed while reading our JSON header
if (!s.writable)
return;
// Immediately close the socket when either:
// * We receive a malformed JSON header
// * Or the source socket id is already used
// * Or the destination socket is not connected
// You could extend this check more if you wanted, for example
// to perform authentication.
if (err
|| typeof result !== 'object'
|| result === null
|| (typeof result.id !== 'string' && typeof result.id !== 'number')
|| (typeof result.destId !== 'string' && typeof result.destId !== 'number')
|| sockets[result.id]
|| !(dest = sockets[result.destId])
|| dest.busy)
return s.destroy();
var id = result.id;
sockets[id] = s;
// Set a flag on each socket to allow exclusive communication
// between connected sockets
s.busy = dest.busy = true;
// Hook the sockets up together, allowing the closing of either
// socket to close the other
s.pipe(dest).pipe(s);
s.on('close', function() {
delete sockets[id];
});
});
}).listen(port);
function readJSON(s, cb) {
var buf = '';
(function read() {
var chunk = s.read();
if (chunk === null)
return s.once('readable', read);
for (var i = 0; i < chunk.length; ++i) {
// 10 === LF (\n)
if (chunk[i] === 10) {
// Check if there is leftover data that is not
// a part of our JSON message that we need to
// put back onto the socket
if (i < (chunk.length - 1))
s.unshift(chunk.slice(i + 1));
buf += chunk.toString('utf8', 0, i);
var result = tryParseJSON(buf);
if (result instanceof Error)
cb(result);
else
cb(null, result);
return;
}
}
buf += chunk.toString('utf8');
// TODO: implement `buf.length` check to make sure we don't
// buffer indefinitely
})();
}
// This is merely an optimization since v8 currently does not
// optimize any functions containing a `try-catch` or `try-finally`.
// By isolating the `try-catch` needed for JSON parsing, we can limit
// the deoptimization.
function tryParseJSON(str) {
try {
return JSON.parse(str);
} catch (ex) {
return ex;
}
}
。之后,两个插座都将关闭。