I've got a little app that generates a code and stores it in mongodb(My chrome browser). Another user(My firefox browser) enters the given code and broadcasts it to let my chrome know that he's there.
Now i want my chrome browser to emit an agreement to itself and my firefox browser so they both get parsed by the same function the moment the agreement is emitted.
The point however is that i only get 1 console log in my terminal which leads me to think that only Chrome(or Firefox, which i doubt) is listening to the emit.
Can anyone take a look why not both browsers receive the 'agreement' emit?
My app.js: (The on connection part)
io.sockets.on('connection', function (socket) {
socket.on('code_game', function (data) {
if (codeToUse == data.code) {
//The receiving end received the proper code from the sending end
console.log(data.secondUser + ' is verbonden via de code: ' + data.code);
//Emit to all parties to let everyone know there's a connection
socket.emit('agreement', {
userOne: {
name: 'Timen',
code: codeToUse
},
userTwo: {
name: data.secondUser,
code: data.code
}
});
}
});
});
And the JS file being called in my view: (sendToFirstUser is Firefox in this case)
var receivingUsersCode = false;
var receivingUsersName = false;
var socket = io.connect('http://localhost');
socket.on('agreement', function (data) {
console.log("hooray");
});
function setReceivingData(code, username) {
receivingUsersCode = code;
receivingUsersName = username;
ding = 'drie';
$('#new_game').css('display', 'block');
$('.theCode').html(receivingUsersCode);
}
function sendToFirstUser(code, username) {
socket.emit('code_game', { code: code, secondUser: username});
}
I'm not sure I understand exactly what you're asking. But it seems to me like you're asking why both your Chrome and Firefox browser aren't emitting an 'agreement' event. If that's it, I think you've answered your own question:
"Another user(My firefox browser) enters the given code and broadcasts it to let my chrome know that he's there."
//Starts broadcasting to other clients
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('code_game', { code: req.body.code, secondUser: req.body.secondUser});
});
Your firefox browser only emits to other clients (your chrome browser) through socket.broadcast.emit. So, only the chrome browser receives the 'code_game' event on the browser side. But in your browser side code, the client emits the 'agreement' event when it receives the 'code_game' event:
socket.on('code_game', function (data) {
if (receivingUsersCode == data.code) {
console.log(data.secondUser + ' is is connected via code: ' + data.code);
listenForMutualConnection();
socket.emit('agreement', {
userOne: {
name: receivingUsersName,
code: receivingUsersCode
},
userTwo: {
name: data.secondUser,
code: data.code
}
});
}
});
Since only the chrome browser is receiving the 'code_game' event, it's also the only one emitting the 'agreement' event.
Related
I have developed an online experiment with oTree which is a framework for developing experiments.
I have implemented the following codes for the measurement of the input values in a form field:
$('document').ready(function () {
$('#id_decl_ic_2').on('input', function () {
input_value = $('#id_decl_ic_2').val();
clearTimeout(timeout)
timeout = setTimeout(function () {
if ($('#id_decl_ic_2').val() == input_value) {
form_id = "formfield_ic_2";
counter_2++;
ip_time = Date.now();
input = {
form_id: form_id,
input_counter: counter_2,
input_time: ip_time,
input_value: input_value,
}
}
console.log(input);
}, 1000)
})
})
The code perfectly works on the local server (the development server of oTree) and I assume also on every normal webpage.
I hosted my experiment on the cloudserver Heroku. There the function causes an internal server error. The same happened with the following JS function:
window.onload = function() {
//do smomething
};
The problem seems to be the respective query selector and the JS handler.
Did anyone ever encounteres the same problem? Does anyone have a solution for the problem? Can I try other event handlers?
In my Chrome extension, I'm trying to exchange data between an internal web page of the extension chrome-extension://myExtensionId/path/to/web/page.html and content scripts.
So, in order to make this data persistent among different content scripts, I'm trying to save it as global variables in the extension's background! I do so using message passing.
My problem is:
When I try to send a response back from the background I get this error:
Error in event handler for (unknown): TypeError: sendResponse is not a
function
I followed the documentation's examples and this is my attempt:
In the scriptOfTheInternalPage.js :
var message = {
'order': 'setData',
'varName': 'myArray',
'data': myArray
};
extPort.postMessage(message, function (response) {
console.log('response:\n', JSON.stringify(response));
});
In background.js :
var globals = {
'myArray': [],
...
};
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(
function (message, sender, sendResponse) {
console.log(
'the port received this message:\n', JSON.stringify(message), '\n',
(sender.tab) ? ' from tab #' + sender.tab.id : ' from the extension!'
);
if (message.order === 'setData') {
globals[message.varName] = message.data;
sendResponse({'response': 'data saved!'}); //<=====
}
return true; //<=== tried to return true here as well;
});
});
Does this error means I should create a brand new function outside of the onMessage event listener?
I'm confused! What am I missing?
Port's onMessage event listeners do not have the same signature as runtime.onMessage. You don't get sender and sendResponse parameters, only the message. Returning true has no effect either.
To reply to a message, you need to use the port itself. This is covered by examples:
port.onMessage.addListener(function(msg) {
if (msg.joke == "Knock knock")
port.postMessage({question: "Who's there?"});
}
So you do need an onMessage listener on both sides, and some way to track requests (unique ID?) if several can be made.
My intention is for one message to be passed to the worker after it is created, and for that message to be logged by the worker and a reply to be sent back. What happens is that the message sent to the web worker is logged twice, and only one reply is sent. If you refresh the page or pause execution using developer tools, the message is correctly logged once.
I created a miniature extension to demonstrate this. There is a background script listening for a click on the browser action button. When it is clicked, a new tab is opened, and this tab generates 2 web workers. These workers listen for messages and log them, and send a reply stating that the message was recieved. The newly opened tab then sends the message, and logs the reply.
Google drive with all of the files needed to run this as a chrome extension
Image demonstrating the double logging of the message
Some references:
general web worker
use
.postMessage to
worker
chrome browser action
chrome tabs API
I have been working on my extension for a while now and have run into all sorts of fun bugs, particularly with async code. In the end I was always able to either debug them myself or find a reference that explained the problem. Thank you for any help you can give!
background.js
const tabUrl = chrome.extension.getURL("tab.html");
function browserActionCallback(tab) {
function createResultsTab() {
chrome.tabs.create({
"url": tabUrl,
"index": tab.index + 1
}, function() {
console.log("Tab created");
});
}
(function tabHandler() {
chrome.tabs.query({"url":tabUrl}, (tabQueryResults) => {
if (tabQueryResults.length > 0) {
chrome.tabs.remove(tabQueryResults[0].id, () => {
createResultsTab();
});
} else {
createResultsTab();
}
});
})();
}
chrome.browserAction.onClicked.addListener((tab) => {
browserActionCallback(tab);
});
tab.js
function createWorkers(num) {
/*in original extension I intended to let the user change number of workers in options*/
var workers = new Array(num);
for (let i = 0; i < num; i++) {
workers[i] = new Worker("worker.js");
}
return workers;
}
function messageWorkers(workers) {
let len = workers.length
for (let i = 0; i < len; i++) {
let message = "Connection " + i + " started";
workers[i].postMessage(message);
workers[i].onmessage = function(e) {
console.log(e.data);
}
}
}
var numWorkers = 2;
const WORKERS = createWorkers(numWorkers);
console.log("Before");
messageWorkers(WORKERS);
console.log("After");
worker.js
onmessage = function(msg) {
console.log(msg.data);
postMessage("Worker reply- " + msg.data);
}
EDIT 1: changing the tab.js messageWorkers function's for loop such that onmessage is set before postMessage does not change the results. Sending multiple messages also doesn't change results. If I have a console.log statement at the start of worker's onmessage function which logs that the function has begun, it too logs twice. To reiterate, this only happens when this tab is created by the background script and not when the page is refreshed or debugger is used.
EDIT 2: in the devtools console, there is a drop down menu to choose between top and workers. Checking the option 'selected context only' makes the repeated logging disappear, however this view is a little narrower than I would like
I can confirm this issue. Sample code to reproduce it:
index.js
function worker() {
console.log('this logged twice');
}
const workerBlob = new Blob(
[worker.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]],
{type: 'text/javascript'}
);
const workerBlobUrl = URL.createObjectURL(workerBlob);
new Worker(workerBlobUrl);
Use index.js as a Chrome extension background script and "this logged twice" will be logged twice when loading the extension or re-launching Chrome.
I am connection through Vertx eventbus (SockJS to my Java based backend. Everything work fine, However, I cannot find a way to send an initial message.
Is there a way to send back data when SockJS bridge receives SOCKET_CREATED to the sockjs browser side?
Thank you.
Taken from their documentation:
if (event.type() == SOCKET_CREATED || event.type() == SOCKET_CLOSED)
{
//...
vertx.eventBus().publish("fromServer", jmsg.toJSONString());
}
Your event instantiation may be different, but that would be how you check for the specific event and run code after it has occurred
You can check this code , where I'm using EventBus.
Here is the Reference code
this.eventBus = new EventBus(this.URL);
this.eventBus.onopen = (e) => {
this._opened = true;
console.log("open connection");
this.callHandlers('open', e);
this.eventBus.publish("http://localhost:8082", "USER LOGIN INFO");
this.eventBus.registerHandler("http://localhost:8081/pushNotification", function (error, message) {
console.log(message.body);
//$("<div title='Basic dialog'>Test message</div>").dialog();
});
}
this.eventBus.onclose = (e) => {
this.callHandlers('close', e);
}
}
I created a simple chatroom using socket.io. I have these scripts in my index.html :
var socket = io.connect('http://imageworkz.asia:8080');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatechat', function (username, data) {
$('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
socket.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
when i change the connection to http://localhost:8080 and start it using 'node app.js' command in console, it works fine but when I upload it and change it to http://imageworkz.asia:8080, it is not working whenever I go to url: http://imageworkz.asia:8080. Am I missing something or are there still things I should do to make it work when it is uploaded? or am I going to the wrong url? Thanks!
Try updating your node.js version to the latest one on the net (http://imageworkz.asia:8080).
Also check whether all necessary node modules are installed on the net, and if needed, change the logic such that you dont require prompt() to transmit a message.
I'm not completely sure, but I think this should work:
var socket = io.connect('http://imageworkz.asia');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatechat', function (username, data) {
$('#conversation').append(''+username + ': ' + data + '');
});
// listener, whenever the server emits 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('' + key + '');
});
});
// on load of page
$(function(){
// when the client clicks SEND
$('#datasend').click( function() {
var message = $('#data').val();
$('#data').val('');
// tell server to execute 'sendchat' and send along one parameter
socket.emit('sendchat', message);
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
it just removes :8080