I wrote a mqtt client.js, but realized I need multiple instances of this script so I rewrote it into a class.
Now I ended up with a lot of 'this.foo' references vor my variables, which made me wonder, is this the correct way of using classes in javascript?
Here´s how part of my class looks like:
this.client = mqtt.connect("mqtts://" + this.host, options); // mqtts for tls connection
// client event handling
this.client.on("connect", () => {
log.write("LOG_INFO", "PubClient connected to Broker: " + this.host + ":" + this.settings.port);
this.client.publish("client/publisher/status", "online", { qos: 1, retain: true });
this.clientToSocket.pubConnect(true);
});
this.client.on("close", () => {
//log.write("LOG_INFO", "PubClient close");
});
this.client.on("disconnect", (packet) => {
log.write("LOG_INFO", "PubClient disconnected. Reasoncode: " + packet.reasoncode);
});
this.client.on("offline", () => {
log.write("LOG_INFO", "PubClient offline");
this.clientToSocket.pubConnect(false);
});
this.client.on("error", (err) => {
//log.write("LOG_ERR", "PubClient Error: " + err.message);
});
this.client.on("packetreceive", (packet) => {
//log.write("LOG_INFO", "PubClient packet received: " + packet.cmd);
});
}
}
publish(topic, qos, msg) {
if(this.client !== undefined) {
this.client.publish(topic, msg, { qos: parseInt(qos), retain: true });
//log.write("LOG_INFO", "Publishing Message with: topic: " + topic + " payload: " + msg);
} else {
log.write("LOG_ERR", "Error: Publish not possible because client undefined");
}
}
close() {
if(this.client !== undefined) {
this.client.end();
log.write("LOG_INFO", "PubClient closing");
}
}
}
You can simplify it, using local variables. When work is done can assign to this. You can also use restructure to use the variables.
Local Var
constructor() {
const client = mqtt.connect("mqtts://" + host, options); // mqtts for tls connection
client.on("close", () => {
//log.write("LOG_INFO", "PubClient close");
});
this.client = client;
}
De-Structure:
doSomthingOnClient() {
const {client} = this // destrcuture
client.get() // use it
}
Whole class:
class Client {
constructor() {
const client = mqtt.connect("mqtts://" + host, options); // mqtts for tls connection
client.on("connect", () => {
log.write(
"LOG_INFO",
"PubClient connected to Broker: " + host + ":" + settings.port
);
client.publish("client/publisher/status", "online", {
qos: 1,
retain: true,
});
clientToSocket.pubConnect(true);
});
client.on("close", () => {
//log.write("LOG_INFO", "PubClient close");
});
client.on("disconnect", (packet) => {
log.write(
"LOG_INFO",
"PubClient disconnected. Reasoncode: " + packet.reasoncode
);
});
this.client = client;
}
getClient() {
return this.client;
}
doSomthingOnClient() {
const {client} = this // destrcuture
client.get() // use it
}
}
Related
I'm new to socket.io. I have a working message chat set up and I'm trying to add names to the messages. I have a var called name which holds each users name who has logged in. below is the code.
On the HTML page that holds the chat. chat-room.html
const room = 'waiting';
const socket = io('/tech');
$('form').submit(() => {
let msg = $('#m').val();
socket.emit('message', { msg, room });
$('#m').val('');
return false;
});
socket.on('connect', () => {
// emiting to everybody
socket.emit('join', { room: room });
})
socket.on('message', (msg) => {
$('#messages').append($('<li>').text(name + msg));
})
On the server script. index.js
const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const port = 3001;
server.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
app.get('/', (req, res) => {
res.sendFile(__dirname + '/virtualsim/learning/chat-room.html');
});
app.get('/trainees', (req, res) => {
res.sendFile(__dirname + '/virtualsim/learning/chat-room2.html');
});
const tech = io.of('/tech');
tech.on('connection', (socket) => {
socket.on('join', (data) => {
socket.join(data.room);
tech.in(data.room).emit('message', `joined ${data.room} room!`);
})
socket.on('message', (data) => {
console.log(`message: ${data.msg}`);
tech.in(data.room).emit('message', data.msg);
});
socket.on('disconnect', () => {
console.log('user disconnected');
tech.emit('message', 'user disconnected');
})
})
Obvious, the way I have it now just sends back the user his or her name for every message sent, even messages send by other users. I need to add the variable name to the server script some how and I'm having difficulties getting it to work. Thanks for any help. John
Here is my Frontend code for set the username
<script>
const form = document.querySelector("form");
const input = document.querySelector(".input");
const messages = document.querySelector(".messages");
const username = prompt("Please enter a username: ", "");
const socket = io();
socket.on("old_message", {message: "hello"});
form.addEventListener("submit", function(event) {
event.preventDefault();
addMessage(username + ": " + input.value);
socket.emit("chat_message", {
message: input.value
});
input.value = "";
return false;
}, false);
socket.on("chat_message", function(data) {
addMessage(data.username + ": " + data.message);
});
socket.on("user_join", function(data) {
addMessage(data + " just joined the chat!");
});
socket.on("user_leave", function(data) {
addMessage(data + " has left the chat.");
});
socket.on("old_message", function() {
console.log('----data', data);
});
socket.on("getList", function(data) {
console.log('----MessageList', data);
});
addMessage("You have joined the chat as '" + username + "'.");
socket.emit("user_join", username);
socket.emit("old_message")
function addMessage(message) {
const li = document.createElement("li");
li.innerHTML = message;
messages.appendChild(li);
window.scrollTo(0, document.body.scrollHeight);
}
Here is backend code
const users = []; io.on('connection', (socket) => { socket.on('user_join', (data) => {
this.username = data;
// here check in DB with sender, receiver if record not exist then create
users.push({
socketId: socket.id,
userId: data,
});
socket.broadcast.emit('user_join', data); });
socket.on('chat_message', async (data) => {
const a = {
sender: data.senderId,
receiver: data.receiverId,
type: 'TEXT',
message: data.message,
};
await model.conversations.create(a);
data.username = this.username;
socket.broadcast.emit('chat_message', data); });
socket.on('disconnect', (data) => {
socket.broadcast.emit('user_leave', this.username); });
socket.on('old_message', async (data) => {
const messageList = await model.conversations.findAll({
where: {
sender: data.senderId,
receiver: data.receiverId,
},
});
socket.broadcast.emit('getList', messageList); }); });
Thanks for the answers back. I have figured out what I had to do.
First (on the HTML page) I had to emit the var name which holds all the users names to the server script on connect. This gives the proper name when one enters the room.
socket.on('connect', () => {
socket.emit('join', { room: room, name: name });
})
Then I added it to the messages being sent
$('form').submit(() => {
let msg = $('#m').val();
socket.emit('message', { name, msg, room });
$('#m').val('');
return false;
});
Then on the server script I added.
On connect
tech.in(data.room).emit('message', `${data.name} joined ${data.room} room!`);
Then again for the messages being sent
tech.in(data.room).emit('message', data.name + data.msg);
I'm sure there is a better way to join the names and messages but like I said I'm new to socket and I have spent way too much time on this :) If you know a better way please do let me know. Thanks!
prompt for the name first, then append it to the start of every message they emit
socket.emit(name+msg, ()=>{...});
I am new to JS.
I am trying to build API server, this server must received data from other server using socket.
Currently I am using net library, I am facing a problem.
I should get data to check whether hardware worked or not, but I only get
undefiend(empty array).
I found some sources making async function to get called, but still I can't get it.
here is my code.
router.post("/Updated", async function(req, res, next) {
.....
//connect to station server for locking
var data = {
cmd: "lockStationQuery",
stationId: STATION_ID,
powerBankId: POWER_BANK_ID,
userId: USER_ID,
number: channelValue
};
var stringData = JSON.stringify(data);
var jsonData = JSON.parse(stringData);
var [client, recvData] = await getConnectionSocket(
USER_ID,
res,
merchant_uid,
amount
);
let successToWriteData = await writeData(client, stringData);
//Fail to send data to lock the Station
if (!successToWriteData) {
res.status(500).json({
RESULT: "FAIL",
REASON:
"error code 504"
});
res.end();
return;
}
console.log("received data", recvData); //this is empty array
jsonData = JSON.parse(recvData[0]);
Here is my getConnectionSocket function.
async function getConnectionSocket(USER_ID, res, merchant_uid, amount) {
//서버에 해당 포트로 접속
var client = "";
var recvData = [];
var local_port = "";
let status = {};
client = net.connect({ port: 8999, host: "localhost" }, function() {
console.log(
"connect log======================================================================"
);
console.log("connect success");
console.log("local = " + this.localAddress + ":" + this.localPort);
console.log("remote = " + this.remoteAddress + ":" + this.remotePort);
local_port = this.localPort;
this.setEncoding("utf8");
this.setTimeout(300000); // timeout : 10분
console.log("client setting Encoding:binary, timeout:300000");
console.log("client connect localport : " + local_port);
});
// 접속 종료 시 처리
client.on("close", function() {
console.log("client Socket Closed : " + " localport : " + local_port);
});
// 데이터 수신 후 처리
await client.on("data", function(data) {
console.log(
"data recv log======================================================================"
);
recvData.push(data);
console.log(recvData); //I want this data
console.log("data.length : " + data.length);
console.log("data recv : " + data);
let jsonData = JSON.parse(data);
if (jsonData.cmd === "removedPowerBank") {
if (jsonData.errorCode !== 0) {
//환불
console.log("환불 시작");
let cancel = cancelOrder(merchant_uid, USER_ID, res);
//여기서 환불 purchase db에 쓰기
} else {
console.log("PURCHASE 성공후 디비에 씀");
//구매 purchase db에 쓰기(getRentId에 썼음)
let purchased = writePurchaseDataInDB(
USER_ID,
res,
merchant_uid,
amount
);
console.log(purchased);
}
}
client.end();
});
client.on("end", function() {
console.log("client Socket End");
});
client.on("error", function(err) {
console.log("client Socket Error: " + JSON.stringify(err));
});
client.on("timeout", function() {
console.log("client Socket timeout: ");
});
client.on("drain", function() {
console.log("client Socket drain: ");
});
client.on("lookup", function() {
console.log("client Socket lookup: ");
});
return [client, recvData]; //recvData is always empty array
}
which way is best to address to resolve this?
Need some clarification on below point
are you getting correct value(s) in below log ? Or you undefined in them too.
console.log("data.length : " + data.length);
console.log("data recv : " + data);
also add this one
console.log("data type : " + typeof(data));
I have the below JavaScript code to develop an app in Fuse Tools. There is one last error that I cannot seem to understand and that is that my variable b64data should be a global variable and is not updating it's value from the capturePhoto function and letting me send the updated value in the submitPhoto function to the server. It should send the base64 encoded value as the picture variable in my POST function. Any help is appreciated!
var Observable = require("FuseJS/Observable");
let ImageTools = require("FuseJS/ImageTools");
var FileSystem = require("FuseJS/FileSystem");
var Base64 = require("FuseJS/Base64");
var Camera = _camera;
var b64data;
var captureMode = Observable();
var flashMode = Observable();
function getCameraInfo() {
Camera.getCameraInfo()
.then(function(info) {
console.log("captureMode: " + info[Camera.INFO_CAPTURE_MODE]);
console.log("flashMode: " + info[Camera.INFO_FLASH_MODE]);
console.log("cameraFacing: " + info[Camera.INFO_CAMERA_FACING]);
console.log("supportedFlashModes: " + info[Camera.INFO_SUPPORTED_FLASH_MODES].join());
captureMode.value = info[Camera.INFO_CAPTURE_MODE];
flashMode.value = info[Camera.INFO_FLASH_MODE];
if (Camera.INFO_PHOTO_RESOLUTIONS in info) {
var availableResolutions = info[Camera.INFO_PHOTO_RESOLUTIONS];
availableResolutions.forEach(function(e) {
console.log(e.width + "x" + e.height);
});
photoResolution = availableResolutions[Math.floor(availableResolutions.length * 0.4)];
var options = {};
options[Camera.OPTION_PHOTO_RESOLUTION] = photoResolution;
Camera.setPhotoOptions(options)
.then(function() {
console.log("New photo options set: " + JSON.stringify(options));
})
.catch(function(error) {
console.log("Failed to set photo options: " + error);
});
}
})
.catch(function(err) {
console.log("Failed to get camera info: " + err);
});
}
getCameraInfo();
function nextFlashMode() {
if (flashMode.value == Camera.FLASH_MODE_AUTO) return Camera.FLASH_MODE_ON;
else if (flashMode.value == Camera.FLASH_MODE_ON) return Camera.FLASH_MODE_OFF;
else if (flashMode.value == Camera.FLASH_MODE_OFF) return Camera.FLASH_MODE_AUTO;
else throw "Invalid flash mode";
}
function setCaptureMode(cm) {
Camera.setCaptureMode(cm)
.then(function(mode) {
captureMode.value = mode;
console.log("Capture mode set to: " + mode);
})
.catch(function(err) {
console.log("Failed to set capture mode: " + err);
});
}
function capturePhoto() {
Camera.capturePhoto()
.then(function (photo) {
photo.save()
.then(function(filePath) {
console.log("Photo saved to: " + filePath);
var arrayBuff = FileSystem.readBufferFromFileSync(filePath);
var b64data = Base64.encodeBuffer(arrayBuff); // send this to the backend
photo.release();
})
.catch(function(error) {
console.log("Failed to save photo: " + error);
photo.release();
});
})
.catch(function (error) {
console.log("Failed to capture photo: " + error);
});
}
var isRecording = Observable(false);
var recordingSession = null;
function startRecording() {
isRecording.value = true;
Camera.startRecording()
.then(function (session) {
recordingSession = session;
})
.catch(function (error) {
console.log("Failed to start recording: " + error);
isRecording.value = false;
});
}
function stopRecording() {
isRecording.value = false;
recordingSession.stop()
.then(function (recording) {
router.push("VideoPage", recording.filePath());
})
.catch(function (error) {
console.log("Failed to stop recording: " + error);
});
recordingSession = null;
}
var cameraBack = true;
function flipCameraFacing() {
var front = Camera.CAMERA_FACING_FRONT;
var back = Camera.CAMERA_FACING_BACK;
Camera.setCameraFacing(cameraBack ? front : back)
.then(function (newFacing) {
cameraBack = newFacing == back;
getCameraInfo();
console.log("Camera facing set to: " + (newFacing == back ? "back" : "front"));
})
.catch(function (err) {
console.log("Failed to set camera facing: " + err);
});
}
function changeFlashMode() {
Camera.setFlashMode(nextFlashMode())
.then(function(newFlashMode) {
flashMode.value = newFlashMode;
console.log("Flash mode set to: " + flashMode.value);
})
.catch(function(err) {
console.log("Failed to set flash mode: " + err);
});
}
var name = Observable();
var email = Observable();
var market = Observable();
module.exports = {
name: name,
email: email,
market: market,
b64data: b64data,
submitPhoto: submitPhoto,
captureMode: captureMode,
setCaptureModePhoto: function () { setCaptureMode(Camera.CAPTURE_MODE_PHOTO); },
setCaptureModeVideo: function () { setCaptureMode(Camera.CAPTURE_MODE_VIDEO); },
capturePhoto: capturePhoto,
startRecording: startRecording,
stopRecording: stopRecording,
isRecording: isRecording,
flipCameraFacing: flipCameraFacing,
flashMode: flashMode,
changeFlashMode: changeFlashMode,
}
function submitPhoto(){
console.log("name: "+name);
console.log("email: "+email);
console.log("market: "+market);
fetch('http://fanbeauties.com/app/submit-photo.php?pass=MY_PASS', {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: '&name='+name+'&email='+email+'&market='+market+'&picture='+b64data
});
};
May be because of you are declaring b64data again in capturePhoto function on line 72 in your shared code.
try
b64data = ...
instead of
var b64data = ...
i need remove socket from server after execute socket.disconnect()
users = {}
ids_disconnect = []
io.of('/example')
.on('connection', function (socket) {
var user_id = socket.decoded_token.user;
if(users[user_id] === undefined){
users[user_id] = {"socket": socket};
} else {
ids_disconnect.push(users[user_id].socket.id);
users[user_id].socket.disconnect(true);
users[user_id] = {"socket": socket};
}
console.log("User Connect: " + user_id + " SocketID: " + socket.id);
//disconnect client
socket.on('disconnect', function () {
console.log('User Disconnect ' + user_id);
if(ids_disconnect.indexOf(socket.id) != -1){
console.log('Disconnect Force: ' + user_id );
ids_disconnect.splice(ids_disconnect.indexOf(socket.id),1)
} else {
delete users[user_id];
}
});
});
};
this my code but socket cant remove from server.
sorry for my english
You have to listen to the disconnect event before triggering it.
users = {}
ids_disconnect = []
io.of('/example')
.on('connection', function(socket) {
var user_id = socket.decoded_token.user;
//disconnect client
socket.on('disconnect', function() {
console.log('User Disconnect ' + user_id);
if (ids_disconnect.indexOf(socket.id) != -1) {
console.log('Disconnect Force: ' + user_id);
ids_disconnect.splice(ids_disconnect.indexOf(socket.id), 1)
} else {
delete users[user_id];
}
});
if (users[user_id] === undefined) {
users[user_id] = {
"socket": socket
};
} else {
ids_disconnect.push(users[user_id].socket.id);
users[user_id].socket.disconnect(true);
users[user_id] = {
"socket": socket
};
}
console.log("User Connect: " + user_id + " SocketID: " + socket.id);
});
};
I would like to use websockets to send updates from the server to the clients.
I know I can use Server Sent Events but Internet Explorer doesn't have great compatibility with it so I prefer to use websocket.
The TotalJs WebSocket allow me to use it like a client?
I'm trying to do this: (TotalJs Websocket Example)
exports.install = function(framework) {
framework.route('/');
framework.route('/send/', send_message);
framework.websocket('/', socket_homepage, ['json']);
};
function send_message() {
var controller = this;
var socket = new WebSocket('ws://127.0.0.1:8000/');
socket.onopen = function() {
socket.send(encodeURIComponent(JSON.stringify({ message: "send_message" })));
};
socket.close();
socket = null;
}
function socket_homepage() {
var controller = this;
controller.on('open', function(client) {
console.log('Connect / Online:', controller.online);
client.send({ message: 'Hello {0}'.format(client.id) });
controller.send({ message: 'Connect new user: {0}\nOnline: {1}'.format(client.id, controller.online) }, [], [client.id]);
});
controller.on('close', function(client) {
console.log('Disconnect / Online:', controller.online);
controller.send({ message: 'Disconnect user: {0}\nOnline: {1}'.format(client.id, controller.online) });
});
controller.on('message', function(client, message) {
console.log(message);
if (typeof(message.username) !== 'undefined') {
var old = client.id;
client.id = message.username;
controller.send({ message: 'rename: ' + old + ', new: ' + client.id });
return;
}
// send to all without this client
message.message = client.id + ': ' + message.message;
console.log(message);
controller.send(message);
});
}
When someone connect to http://127.0.0.1/send all clients connected to the server will receive a message.
Node.js doesn't have native WebSocket support so the send_message() function does not work. I would like to use TotalJs Websocket support but I don't know how to use it like a client.
Thats it.
Thank you very much.
I know this is the not best way but I used a global variable to resolve.
exports.install = function(framework) {
framework.route('/');
framework.route('/send/', send_message);
framework.websocket('/', socket_homepage, ['json']);
};
function send_message() {
if (websocket == null) return;
websocket.send({ message: "Hello World!" });
}
var websocket = null;
function socket_homepage() {
//var controller = this;
websocket = this;
websocket.on('open', function(client) {
console.log('Connect / Online:', websocket.online);
client.send({ message: 'Hello {0}'.format(client.id) });
websocket.send({ message: 'Connect new user: {0}\nOnline: {1}'.format(client.id, websocket.online) }, [], [client.id]);
});
websocket.on('close', function(client) {
console.log('Disconnect / Online:', websocket.online);
websocket.send({ message: 'Disconnect user: {0}\nOnline: {1}'.format(client.id, websocket.online) });
});
websocket.on('message', function(client, message) {
console.log(message);
if (typeof(message.username) !== 'undefined') {
var old = client.id;
client.id = message.username;
websocket.send({ message: 'rename: ' + old + ', new: ' + client.id });
return;
}
// send to all without this client
message.message = client.id + ': ' + message.message;
console.log(message);
websocket.send(message);
});
}