Retrieving message from Flask socket raises "Invalid left-hand side in assignment" - javascript

I'm trying to create a channel I can join using Flask socketio and Javascript.
All of my debug statements are firing, indicating that everything is initializing, but when I try to capture the message emitted from my Flask/socket-io route, which I assume executes the actual room change, I get Uncaught ReferenceError: Invalid left-hand side in assignment in my console referring to the line in my JS file let message = data.msg; in the section:
socket.on('status', data => {
let message = data.msg;
document.querySelectorAll('#messages') += message;
});
I tried writing data.msg various ways (e.g., with backticks, like this ${data.msg} surrounded by backticks as if part of a formatted string, etc), but nothing worked. I've read the docs, and they were sparse on details. There appear to be zero examples of how to do this effectively on the web. Most people seem to favor node.js, but I'm a Flask guy.
How can I join my room, and chat only in that room? I'll need to allow users to create as many as they want.
Here's the route in Flask:
#socketio.on('join')
def on_join(data):
username = data['username']
room = data['room']
join_room(room)
emit("status", {'msg': username + 'has joined the room'}, room=room)
Here's the accompanying JS:
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
if (!socket) console.log("Socket not connected!");
socket.on('connect', () => {
console.log("socket connected");
// after socket connect, configure channel button
document.querySelectorAll('button').forEach(button => {
button.onclick = () => {
console.log("button click fired!");
let username = localStorage["login"]
let room = button.dataset.room;
console.log("ChannelName" + room);
socket.emit("join", {'username':username, "room":room});
};
});
socket.on('status', data => {
console.log("JOINED!")
let message = data.msg;
document.querySelectorAll('#messages') += message;
});
Note, the error occurs right before assignment to the #message div.
EDIT
Unpacking the error reveals multiple references to the minified JS file flask socket-io requires. It is in the <head> section of layout.html. Placement in the <body> caused serious errors impeded development of all socket-related functionality.
messages:134 Uncaught ReferenceError: Invalid left-hand side in assignment
at r.socket.on.data (messages:134)
at r.n.emit (socket.io.min.js:1)
at r.onevent (socket.io.min.js:1)
at r.onpacket (socket.io.min.js:1)
at n.<anonymous> (socket.io.min.js:1)
at n.emit (socket.io.min.js:1)
at n.ondecoded (socket.io.min.js:1)
at s.<anonymous> (socket.io.min.js:1)
at s.n.emit (socket.io.min.js:1)
at s.add (socket.io.min.js:2)

This is not valid: document.querySelectorAll('#messages') += message;
document.querySelectorAll('#messages') Would give you a list of DOM elements.
Also, element id's are supposed to be unique, so you should probably be using document.querySelector('#messages') so retrieve just one element, and not a list.
You can not add/concat text to an element directly this way. You probably are looking for something like document.querySelector('#messages').innerHTML += message;

Related

Can't connect to websocket

I'm new to Blockchain and I want to understand how to use JS to open a Websocket, the code is from Blockcypher.com docs https://www.blockcypher.com/dev/dash/?javascript#using-websockets
// Get latest unconfirmed transactions live
var ws = new WebSocket("wss://socket.blockcypher.com/v1/dash/main");
var count = 0;
ws.onmessage = function (event) {
var tx = JSON.parse(event.data);
var shortHash = tx.hash.substring(0, 6) + "...";
var total = tx.total / 100000000;
var addrs = tx.addresses.join(", ");
$('#browser-websocket').before("<div>Unconfirmed transaction " + shortHash + " totalling " + total + "DASH involving addresses " + addrs + "</div>");
count++;
if (count > 10) ws.close();
}
ws.onopen = function(event) {
ws.send(JSON.stringify({event: "unconfirmed-tx"}));
}
The browser console displays this error: Firefox can’t establish a connection to the server at wss://socket.blockcypher.com/v1/dash/main.
Note: I have a token provided by Blockcypher but the code example they provide doesn't ask for any token. Is the code bad? is it missing something?
The problem is not in your code but with the server not responding as expected.
It could be a server issue or you may need to be pre approved to access the resource (assuming they are whitelisting IP addresses which I doubt).
Also, check out the rest of the code, it has a placeholder for a token that you may need to connect (the error you see now is way before the token is requested).
You can always change the server name to one of many test servers out there like wss://echo.websocket.org and see the error changing from "Can't establish connection" to something related to the rest of the code.

Error while streaming through Chromecast cast_sender.js

Add chrome cast according to the tutorial.
After adding the Chromecast button, I click it, select an available device from the network, and it is connected. The status "Streaming" is visible in the browser, in fact nothing happens, except for the following error in the console:
TypeError: Cannot read property 'loadMedia' of null
Code:
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: '111111',
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
});
var currentMediaURL =
'https://.....';
var contentType = 'mp4';
var mediaInfo = new chrome.cast.media.MediaInfo(currentMediaURL,contentType);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
console.log('Below variable -mediaInfo ');
console.log(mediaInfo);
console.log('Below variable -request ');
console.log(request);
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
console.log('Below variable -castSession ');
console.log(castSession);
castSession.loadMedia(request).then(
function () {
console.log('Load succeed');
},
function (errorCode) {
console.log('Error code: ' + errorCode);
});
Code testing:
As I understand it, for some reason, the link to the stream is not sent.
There is an interesting question, why does the link to the stream go to the variable contentid although there is a variablecontentUrl?

Sending private messages Discord-api

help me with discord-api. Sending private messages to the user who just logged on to the server. I have the following code:
const robot = new Discord.Client();
robot.on("guildMemberAdd", (gMembAdd) =>
{
gMembAdd.guild.channels.find("name", "test").sendMessage(gMembAdd.toString() + "hello guys");
});
Added the following code:
robot.on("guildMemberAdd", (gMembAdd) =>
{
gMembAdd.guild.channels.find("name", "test").sendMessage(gMembAdd.toString() + "hello guys");
gMembAdd.mentions.users.first().sendMessage("Test");
});
I received an error message. Help me please.
First thing you shouldn't use .sendMessage() as it was deprecated in newer versions. You need to use .send().
When you subscribing to guildMemberAdd you will recieve a GuildMember, from there you can directly send a message:
robot.on("guildMemberAdd", (gMembAdd) => {
gMembAdd.guild.channels.find("name", "test").send(gMembAdd.toString() + "hello guys");
gMembAdd.send("Test");
});
This should send a message directly to the member that joined.

JavaScript issue with import/export modules and Globally defined variables

(note, I'm using Node.js to create a telnet server and handle user input)
I'm having issues using variables/arrays in javascript inside functions in other scripts.
Let me set a simpler example:
var connections = []
is an array in my main.js
Broadcast.js is a function I put in a separate module and attempt to use the broadcast() function in my main.js.
The error I get is stating that connections is undefined. How do get Broadcast.js able to see the connections array in the main.js
~~
For example in my main.js I set an array to handle clients connecting to a server
//point to Telnet library
const Telnet = require('ranvier-telnet');
const logger = require('./logger.js')
var outspeak = []
var connections = []
var clients = []
let server = new Telnet.TelnetServer(rawSocket => {
let telnetSocket = new Telnet.TelnetSocket();
//attaching socket
telnetSocket.attach(rawSocket);
//setting telnet options
telnetSocket.telnetCommand(Telnet.Sequences.WILL, Telnet.Options.OPT_EOR);
//giving clients a name
telnetSocket.name = rawSocket.remoteAddress + ":" + rawSocket.remotePort
//pushing client names to array
clients.push(telnetSocket.name);
//pushing client connections to an array
connections.push(rawSocket);
console.log(`${telnetSocket.name} has connected`)
logger(`${telnetSocket.name} has connected`)
broadcast(telnetSocket.name + " connected.")
telnetSocket.on('data', function (data) {
//broadcast (telnetSocket.name + ">" + data, telnetSocket);
}
function broadcast (message, sender) {
connections.forEach(function (connection) {
//don't want to send it to sender
if (connection === sender) return;
connection.write(`${message} \n`);
});
}
Now inside my main script, I could called that array/push to that array, read from that array, as long as I type out the function inside the main.js file.
And it can easily use the broadcast function.
Now I want to make it more advance and make reduce my lines on my main.js
but once I separate the broadcast function into it's own module.
use strict'
//broadcast function
function broadcast (message, sender) {
connections.forEach(function (connection) {
//don't want to send it to sender
if (connection === sender) return;
connection.write(`${message} \n`);
});
}
module.exports = broadcast
I get a connection undefined error any time I try to invoke that broadcast function. It's like my global variable/array can't be seen by broadcast.js function.
this is how I'm invoking it
// handle input
telnetSocket.on('data', function (data) {
broadcast (telnetSocket.name + ">" + data, telnetSocket);
});
And yes, const broadcast = require('./broadcast.js'); as been added to the file at the top.
Here's the broken code complete:
'use strict'
//point to Telnet library
const Telnet = require('ranvier-telnet');
const logger = require('./logger.js');
const broadcast = require('./broadcast.js');
var connections = []
var clients = []
//had to call message as global variable
//Asan's timestamp functionm
//telnetstuff
console.log("Starting...");
let server = new Telnet.TelnetServer(rawSocket => {
let telnetSocket = new Telnet.TelnetSocket();
//attaching socket
telnetSocket.attach(rawSocket);
//setting telnet options
telnetSocket.telnetCommand(Telnet.Sequences.WILL, Telnet.Options.OPT_EOR);
//giving clients a name
telnetSocket.name = rawSocket.remoteAddress + ":" + rawSocket.remotePort
//pushing client names to array
clients.push(telnetSocket.name);
//pushing client connections to an array
connections.push(rawSocket);
console.log(`${telnetSocket.name} has connected`)
logger(`${telnetSocket.name} has connected`)
broadcast(telnetSocket.name + " connected.")
// handle input
telnetSocket.on('data', function (data) {
broadcast (telnetSocket.name + ">" + data, telnetSocket);
});
//removing client/connection from array
rawSocket.on('end', function () {
clients.splice(clients.indexOf(telnetSocket), 1);
connections.splice(connections.indexOf(rawSocket), 1);
broadcast(telnetSocket.name + " has left.\n");
logger(telnetSocket.name + " has left.");
console.log(telnetSocket.name + " has left.");
});
}).netServer
server.listen(4000);
console.log('ServerRunning...');
logger('>Server started.');
What I'm missing here? Also I apologize in advance this is my first question ever asked and I've gone through as much I could today to even figure out how to ask my question, maybe I'm not using correct lingo/terms? any help is appreciative.
refactor\broadcast.js:5
connections.forEach(function (connection) {
^
ReferenceError: connections is not defined
In nodejs, when you declare a variable not inside any function definitions, it is scoped to the file only. (This is different from browser javascript.) If you want something to be accessible from outside, you need to export it:
module.exports.connections = connections;
Then import it into the other file:
const connections = require(myFile);
This will work as long as you don't try to set the value of the variable in either file, but if you do that they'll end up pointing to separate objects. But mutating it, calling methods on it, etc should work fine.

Chrome packaged app UDP sockets not working

I'm trying to get UDP sockets working for a packaged app using Chrome Canary (currently version 25). I am pretty confused by the fact the UDP example here conflicts with the reference documentation here.
The official example uses this line:
chrome.socket.create('udp', '127.0.0.1', 1337, { onEvent: handleDataEvent }, ...
In Canary using this line results in the error:
Uncaught Error: Invocation of form socket.create(string, string,
integer, object, function) doesn't match definition
socket.create(string type, optional object options, function callback)
Not surprising since that matches the documented form of the function. (I guess the example is out of date?) OK, so I try this...
chrome.socket.create('udp', { onEvent: handleDataEvent }, ...
Canary complains:
Uncaught Error: Invalid value for argument 2. Property 'onEvent':
Unexpected property.
Now I'm confused, especially since this parameter is undocumented in the reference. So I just go with this:
chrome.socket.create('udp', {}, ...
Now it creates OK, but the following call to connect...
chrome.socket.connect(socketId, function(result) ...
...fails with this:
Uncaught Error: Invocation of form socket.connect(integer, function)
doesn't match definition socket.connect(integer socketId, string
hostname, integer port, function callback)
...which is not surprising, since now my code doesn't mention a host or port anywhere, so I guess it needs to be in connect. So I change it to the form:
chrome.socket.connect(socketId, address, port, function (result) ...
At last I can connect and write to the socket OK. But this doesn't cover reading.
Can someone show me a working example based on UDP that can send & receive, so I can work from that?
How do I receive data since the example's onEvent handler does not work? How do I ensure I receive any data on-demand as soon as it arrives without blocking?
The Network Communications doc is not up-to-date. See the latest API doc: https://developer.chrome.com/trunk/apps/socket.html. But the doc doesn't state everything clearly.
I looked into Chromium source code and found some useful comments here: https://code.google.com/searchframe#OAMlx_jo-ck/src/net/udp/udp_socket.h&q=file:(%5E%7C/)net/udp/udp_socket%5C.h$&exact_package=chromium
// Client form:
// In this case, we're connecting to a specific server, so the client will
// usually use:
// Connect(address) // Connect to a UDP server
// Read/Write // Reads/Writes all go to a single destination
//
// Server form:
// In this case, we want to read/write to many clients which are connecting
// to this server. First the server 'binds' to an addres, then we read from
// clients and write responses to them.
// Example:
// Bind(address/port) // Binds to port for reading from clients
// RecvFrom/SendTo // Each read can come from a different client
// // Writes need to be directed to a specific
// // address.
For the server UDP socket, call chrome.socket.bind and chrome.socket.recvFrom/chrome.socket.sendTo to interact with clients. For the client UDP socket, call chrome.socket.connect and chrome.socket.read/chrome.socket.write to interact with the server.
Here's an example:
var serverSocket;
var clientSocket;
// From https://developer.chrome.com/trunk/apps/app_hardware.html
var str2ab=function(str) {
var buf=new ArrayBuffer(str.length);
var bufView=new Uint8Array(buf);
for (var i=0; i<str.length; i++) {
bufView[i]=str.charCodeAt(i);
}
return buf;
}
// From https://developer.chrome.com/trunk/apps/app_hardware.html
var ab2str=function(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
};
// Server
chrome.socket.create('udp', null, function(createInfo){
serverSocket = createInfo.socketId;
chrome.socket.bind(serverSocket, '127.0.0.1', 1345, function(result){
console.log('chrome.socket.bind: result = ' + result.toString());
});
function read()
{
chrome.socket.recvFrom(serverSocket, 1024, function(recvFromInfo){
console.log('Server: recvFromInfo: ', recvFromInfo, 'Message: ',
ab2str(recvFromInfo.data));
if(recvFromInfo.resultCode >= 0)
{
chrome.socket.sendTo(serverSocket,
str2ab('Received message from client ' + recvFromInfo.address +
':' + recvFromInfo.port.toString() + ': ' +
ab2str(recvFromInfo.data)),
recvFromInfo.address, recvFromInfo.port, function(){});
read();
}
else
console.error('Server read error!');
});
}
read();
});
// A client
chrome.socket.create('udp', null, function(createInfo){
clientSocket = createInfo.socketId;
chrome.socket.connect(clientSocket, '127.0.0.1', 1345, function(result){
console.log('chrome.socket.connect: result = ' + result.toString());
});
chrome.socket.write(clientSocket, str2ab('Hello server!'), function(writeInfo){
console.log('writeInfo: ' + writeInfo.bytesWritten +
'byte(s) written.');
});
chrome.socket.read(clientSocket, 1024, function(readInfo){
console.log('Client: received response: ' + ab2str(readInfo.data), readInfo);
});
});

Categories