How can I receive data using socket.io? - javascript

I am running a server using expressjs. Whenever a user accesses to one of my specific url (for this purpose, just imagine it will be https://server.com/test), I want to emit a data to another webserver using socketio, listen to the data and respond to the user with the data I have received.
Few things to note:
My server expects nothing but just an access to the https://server.com/test url.
Another server, which I want to connect using socket.io and obtain data expects me to send an argument of {"got" : "true"} to parameter called "test".
When another server receives the socket emit from my server on parameter "test" with arguments specified above, it simply replies back with an argument {"message" : "true"}
My code is quite simple and looks like this (router) :
const express = require("express");
const router = express.Router();
//const Goal = require("../models/battery_message");
const mongoose = require("mongoose");
const io = require("socket.io-client");
const host = "https://another_server.com"
const socket = io(host, {query:"email=edmund#gmail.com"});
console.log("connected");
router.get('/', function(req,res) {
socket.emit("test_me", {"got" : "true"}, function(data){
exists = data;
console.log(data);
});
});
module.exports = router;
The problem I have is whenever the user accesses my server on https://server.com/test nothing happens, as no response comes like in an infinite loop. My guess is that I need some kind of another socket.emit because another server probably emits its response to the socket too, but I might be wrong.
So to sum up, my question is, what do I need to add in order to successfully get the response from another server?

Related

https api request is not working with https.get(url)

I need to pull the weather API data from
https://api.weatherapi.com/v1/current.json?key=f5f45b956fc64a2482370828211902&q=London
It gives a response when pasted in the web browser as well as in postman. But, once incorporated in javascript https.get it fails by continuously loading the browsers and hanging the terminal with unwanted informations.
app.js :
//jshint esversion:6
const express = require("express");
const https = require("https");
const app = express();
app.get("/",function(req, res){
const url = "https://api.weatherapi.com/v1/current.json?key=f5f45b956fc64a2482370828211902&q=London";
https.get(url,function(response){
//console.log(response);
response.on("data",function(data){
const weatherData = JSON.parse(data);
const temp = weatherData.current.temp_c;
const weatherDescription = weatherData.current.condition.text;
});
});
res.send("Server is up and running");
});
app.listen(3000, function(){
console.log("Started on port 3000");
});
I tried the specific request that you posted using https.get() and it worked for me. So it will be difficult to figure out what is the exact problem without more information, for example about how exactly it is failing for you. What messages are you seeing on the console? How are you accessing the result of the request, so what makes you think that the request didn't work?
But apart from that, that is not how you usually make requests in Node. The "data" event may be emitted multiple times if the response arrives in multiple chunks, so the way you do it will only work if you are lucky and the response arrives in a single chunk. The proper way to do this by hand would be to listen to all "data" events, concatenate the result, and then when the "end" event is emitted, parse the concatenated data. However, it is rather uncommon to do this by hand.
A more common way to do this would be to use a library such as node-fetch to make the request for you. For example like this: fetch(url).then((res) => res.json()).then((weatherData) => { const weatherDescription = weatherData.current.condition.text; }).

i can't figure out why we are using response.on

I've written a code here and I want to know what "response.on" is doing and why we are passing "data", what is this "data".
what exactly that ".on" is used for.
const express = require("express");
const https = require("https");
const app = express();
app.get("/",function(req,res){
const url="https://api.openweathermap.org/data/2.5/weather?q=London&appid=5c8618a9210a11846accc217f3b3084f";
https.get(url,function(respons){
response.on("data",function(data){
const wht = JSON.parse(data)
temp = wht.main.temp
res.send("temp "+ temp)
})
})
})
app.listen(3000, function(){
console.log("running");
});
.on("nameOfEvent", callback) it's a event emitter. So, basically whenever that event is called, that callback will be executed. data is just the name of the event.
In your code there is bug.
You using respons in the argument of function and response inside of function.
Waiting on data of response is documented in https
https://nodejs.org/api/https.html#https_https_get_options_callback
You can read that response is not a classical response from the server but an event listener that listens for stream of data.
It is a low-level interface and in your applications, you should not use them. Lets interest in node-fetch or axios instead if you want only get a response, but not process streams in real-time.

How can I create a websocket using the data im getting from another websocket

Im using a node server to get data from an websocket and I want to create my own websocket and send the data to a react app. Does anyone know any methods or packages for it.
So I do something like your question.
NODE.js side
I used the socket.io library for sending data to my react app.
So for sending I use something like this.
/*Declaration and settings up (you can replace the port)*/
const express = require('express');
const app = express();
let server = require('http').Server(app);
let io = require('socket.io')(server);
server.listen(8081); //PORT of your socket
app.listen(8080); //PORT of your API
/*If you want to do something when a user is connect you can do something like this
"topic" is a string, you can replace by what you want. Here the client (REACT) is
listening on "topic"*/
io.on('connect', (socket) => {
let messageToSend = {
"message": "Hello world!"
};
socket.emit("topic", messageToSend);
});
/*If you simply want to send something just use the io variable. like this*/
io.emit("topic", "What you whant here");
React side
For react side I used socket.io-client
import socketIOClient from "socket.io-client";
/* insert the following code in a function or where you want.*/
let client = socketIOClient("127.0.0.1:8081"); //ip of socket server
/*After define client, you define the topic you want listening and the function you
want to use as callBack. Here I just print data*/
client.on("topic", (data) => {
console.log(data)});
You can find more details on the socket.io-client and socket.io
I hope my answer can be usefull.

How to emit an event in response to an event using socket.io?

I am new to socket.io, and trying to get it to work. I don't know what I am doing wrong here, as it seems super straightforward - yet it is not working. I suppose I am missing something obvious. Hopefully someone else can see what that is.
I am setting up socket.io to work with a node/express server. Here is a simplified version of the test I am trying to do.
Server:
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
/* socket.io test */
io.on('connection', function(socket){
socket.on('helloServer', function(clientMessage){
console.log("Server got 'helloServer' event");
socket.emit('helloClient', { message : "Hi there. We got your message: " + clientMessage.message});
});
});
The client has a function callServer that is called when a user clicks a button in the UI:
var socket = io.connect('http://localhost');
function callServer() {
socket.emit('helloServer', { message : "Hello server!" });
}
socket.on('helloClient', function (serverMessage) {
console.log(serverMessage.message);
});
When I run this code, and click the button that calls callServer, the server does get the event, helloServer, because I see that the console logs the message as expected, but the client never receives a helloClient event. It is as if the socket.emit call within the socket.on response function never gets called.
What am I doing wrong?
It appears to be ok. But, just in case, check this answer with all ways of sending data to clients and try use "io.emit" (to send to all clients). Or try sending a string instead of a json object.
I have tried this example here and it is working, just copied and pasted.

Node JS app only display the first JSON object. Why?

I am trying to write a json object in my node application, integrating the Twilio API. When console logging the object all objects are returned properly but when I write it to the document only the first object is written. Why? How should I change the code to see the same written response as in my console log.
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.get('/', function(req, res) {
var accountSid = 'xxx';
var authToken = 'xxx';
var client = require('twilio')(accountSid, authToken);
client.messages.list({
from: "xxx",
to: "xxx"
}, function(err, data) {
data.messages.forEach(function(message) {
console.log(message.body); // THIS WILL DISPLAY ALL OBJECTS
res.json(message.body); // THIS WILL ONLY DISPLAY THE FIRST OBJECT
});
});
});
app.listen(1337);
I am new to Node JS and think this is easy to solve, but I still can’t find the solution.
res.json(...); sends back the response. You are doing that in the first iteration over the array, hence the client only gets the first message.
If you want to extract body from all messages and send all of them back, then do that. Create an array with the data you want and send it back. Example:
res.json(data.messages.map(function(message) {
return message.body;
}));
You can only call res.json once per request. You're calling it multiple times in a loop. The first time you call it, the browser receives the response, and you'll get a headers already sent exceptions (or something like that) for all other res.json calls.
res.json actually does a data conversion to JSON. I'd be willing to bet there is something it is not dealing with, or it's simply screwing it up. If the response from Twilio is already json, you probably don't need to do that. Try res.send, instead, which just returns whatever you got back.

Categories