Node.js Server - how to pass buttonclick function from client to client

时间:2022-04-21 19:41:54

What I'm trying to do is something like little chat taht I already made with some help. But what I want rly is taht when clicing on button1 (oppens new page) client1 passes buttonclick to client2 and same action happens on client2 (opens new page), something like remote control.

我正在尝试做的事情就像我已经在一些帮助下做的小聊天一样。但是,当我在button1(oppens新页面)上进行clicing时,我想要rly是taht,而client1将buttonclick传递给client2,同样的动作发生在client2上(打开新页面),比如远程控制。

var nowjs = require('now');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.sendFile(__dirname + '/startHTM.htm');
});

io.on('connection', function(socket){
    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });
});

http.listen(8080, function(){
    console.log('listening on *:8080');
});

<!doctype html>
<html>
    <head>
        <title>Socket.IO chat</title>
        <style>
            * { margin: 0; padding: 0; box-sizing: border-box; }
            body { font: 13px Helvetica, Arial; }
            form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
            form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
            form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
            #messages { list-style-type: none; margin: 0; padding: 0; }
            #messages li { padding: 5px 10px; }
            #messages li:nth-child(odd) { background: #eee; }
        </style>
    </head>

    <body>
        <ul id="messages"></ul>
        <form action="">
            <input id="m" autocomplete="off" /><button>Send</button>
        </form>
        <script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
    var socket = io();
    $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
    });
    socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
    });
</script>
    </body>
</html>

Thx for further help!

谢谢你的进一步帮助!

1 个解决方案

#1


1  

Here are few ideas to get you started:

以下是一些可以帮助您入门的想法:

You need to listen for every click event, either on the page itself and send coordinates of the click to the server, or listen for click events on elements and send e.g. an element id with every click event to the server.

您需要在页面本身上监听每个点击事件,并将点击的坐标发送到服务器,或者监听元素上的点击事件并发送,例如每次点击事件到服务器的元素ID。

The server needs to emit that event to every client except the originating one.

服务器需要将该事件发送给除发起者之外的每个客户端。

All clients that recieve such an event from the server need to simulate a click event.

从服务器接收此类事件的所有客户端都需要模拟单击事件。

I'll try to write a simple demo - I'll update the answer when I have a working example.

我将尝试编写一个简单的演示 - 当我有一个工作示例时,我会更新答案。

Update

Take a look at this example on GitHub:

在GitHub上看一下这个例子:

It has a simple Socket.IO server in app.js:

它在app.js中有一个简单的Socket.IO服务器:

var path = require('path');
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static(path.join(__dirname, 'html')));

io.on('connection', s => {
  console.error('socket.io connection');
  s.on('click', d => {
    console.error('click on id '+d.id);
    s.broadcast.emit('click', d);
  });
});

http.listen(3002, () => console.error('Listening on http://localhost:3002/'));

See: https://github.com/rsp/node-socket.io-remote/blob/master/app.js

And client code in html/index.html using jQuery like in your question:

并在您的问题中使用jQuery的html / index.html中的客户端代码:

var ownClick = true;
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
s.on('click', function (d) {
  log('received click message, id ' + d.id);
  ownClick = false;
  $('#'+d.id)[0].click();
  ownClick = true;
});

$('.remote').click(function (e) {
  if (ownClick) {
    log('emitting click message, id ' + e.target.id);
    s.emit('click', {id: e.target.id});
  }
});

(The log() function is defined in the source but I don't include it here for simplicity)

(log()函数在源代码中定义,但为简单起见,我不在此处包含它)

See: https://github.com/rsp/node-socket.io-remote/blob/master/html/index.html

Important issues

There are few important issues here:

这里几乎没有重要的问题:

There is a line with:

有一条线:

$('#'+d.id)[0].click();

and not:

$('#'+d.id).click();

because we want to run a native browser's click() method instead of the jQuery one, which would work differently.

因为我们想要运行本机浏览器的click()方法而不是jQuery方法,这将有所不同。

Also I have a ownClick variable normally set to true except when running a handler for incoming remote click event. That is because we won't to send that event again to other windows. For this example it is not really needed because we are leaving the page with every click but if we stayed on the page then the events would cascade: for example if we had 3 windows and one of them sent a click to the other two, those two would start emulating their own clicks and send those clicks again to the server and again, and again with no end.

此外,我有一个通常设置为true的ownClick变量,除非为传入的远程单击事件运行处理程序。那是因为我们不会再将该事件发送到其他窗口。对于这个例子,它并不是真的需要,因为我们每次点击都会离开页面,但如果我们留在页面上,那么事件就会级联:例如,如果我们有3个窗口,其中一个发出了点击其他两个,那些两个人会开始模仿他们自己的点击次数,然后再次将这些点击次数发送到服务器,并再次无止境地发送。

Here I am making only the elements with class "remote" remotely clickable, mostly because otherwise clicking the link to open new window with that page would click that link in all open windows opening more pages in the process, leading to browser warnings about too many popups, but instead of $('.remote') you could use $('a') to select all links if you want.

在这里,我只使用“远程”类远程可点击的元素,主要是因为否则点击链接打开该页面的新窗口会在所有打开的窗口中单击该链接打开更多页面,导致浏览器警告太多弹出窗口,但您可以使用$('a')来选择所有链接,而不是$('。remote')。

In this example only links with defined IDs will work, because those IDs are sent with the Socket.IO messages.

在此示例中,只有具有已定义ID的链接才有效,因为这些ID与Socket.IO消息一起发送。

#1


1  

Here are few ideas to get you started:

以下是一些可以帮助您入门的想法:

You need to listen for every click event, either on the page itself and send coordinates of the click to the server, or listen for click events on elements and send e.g. an element id with every click event to the server.

您需要在页面本身上监听每个点击事件,并将点击的坐标发送到服务器,或者监听元素上的点击事件并发送,例如每次点击事件到服务器的元素ID。

The server needs to emit that event to every client except the originating one.

服务器需要将该事件发送给除发起者之外的每个客户端。

All clients that recieve such an event from the server need to simulate a click event.

从服务器接收此类事件的所有客户端都需要模拟单击事件。

I'll try to write a simple demo - I'll update the answer when I have a working example.

我将尝试编写一个简单的演示 - 当我有一个工作示例时,我会更新答案。

Update

Take a look at this example on GitHub:

在GitHub上看一下这个例子:

It has a simple Socket.IO server in app.js:

它在app.js中有一个简单的Socket.IO服务器:

var path = require('path');
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static(path.join(__dirname, 'html')));

io.on('connection', s => {
  console.error('socket.io connection');
  s.on('click', d => {
    console.error('click on id '+d.id);
    s.broadcast.emit('click', d);
  });
});

http.listen(3002, () => console.error('Listening on http://localhost:3002/'));

See: https://github.com/rsp/node-socket.io-remote/blob/master/app.js

And client code in html/index.html using jQuery like in your question:

并在您的问题中使用jQuery的html / index.html中的客户端代码:

var ownClick = true;
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
s.on('click', function (d) {
  log('received click message, id ' + d.id);
  ownClick = false;
  $('#'+d.id)[0].click();
  ownClick = true;
});

$('.remote').click(function (e) {
  if (ownClick) {
    log('emitting click message, id ' + e.target.id);
    s.emit('click', {id: e.target.id});
  }
});

(The log() function is defined in the source but I don't include it here for simplicity)

(log()函数在源代码中定义,但为简单起见,我不在此处包含它)

See: https://github.com/rsp/node-socket.io-remote/blob/master/html/index.html

Important issues

There are few important issues here:

这里几乎没有重要的问题:

There is a line with:

有一条线:

$('#'+d.id)[0].click();

and not:

$('#'+d.id).click();

because we want to run a native browser's click() method instead of the jQuery one, which would work differently.

因为我们想要运行本机浏览器的click()方法而不是jQuery方法,这将有所不同。

Also I have a ownClick variable normally set to true except when running a handler for incoming remote click event. That is because we won't to send that event again to other windows. For this example it is not really needed because we are leaving the page with every click but if we stayed on the page then the events would cascade: for example if we had 3 windows and one of them sent a click to the other two, those two would start emulating their own clicks and send those clicks again to the server and again, and again with no end.

此外,我有一个通常设置为true的ownClick变量,除非为传入的远程单击事件运行处理程序。那是因为我们不会再将该事件发送到其他窗口。对于这个例子,它并不是真的需要,因为我们每次点击都会离开页面,但如果我们留在页面上,那么事件就会级联:例如,如果我们有3个窗口,其中一个发出了点击其他两个,那些两个人会开始模仿他们自己的点击次数,然后再次将这些点击次数发送到服务器,并再次无止境地发送。

Here I am making only the elements with class "remote" remotely clickable, mostly because otherwise clicking the link to open new window with that page would click that link in all open windows opening more pages in the process, leading to browser warnings about too many popups, but instead of $('.remote') you could use $('a') to select all links if you want.

在这里,我只使用“远程”类远程可点击的元素,主要是因为否则点击链接打开该页面的新窗口会在所有打开的窗口中单击该链接打开更多页面,导致浏览器警告太多弹出窗口,但您可以使用$('a')来选择所有链接,而不是$('。remote')。

In this example only links with defined IDs will work, because those IDs are sent with the Socket.IO messages.

在此示例中,只有具有已定义ID的链接才有效,因为这些ID与Socket.IO消息一起发送。