I'm new to node.js but I know somewhat about socketstream web framework by using this I can easily call a server side node.js method from JavaScript. I don't know how to do this without using that framework. How can I call the node.js method from JavaScript?
The below code is using socketstream to call server side method. So I want to call the same server side method without using this framework.
ss.rpc('FileName.methodName',function(res){
alert(res);
});
I'd suggest use Socket.IO
Server-side code
var io = require('socket.io').listen(80); // initiate socket.io server
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' }); // Send data to client
// wait for the event raised by the client
socket.on('my other event', function (data) {
console.log(data);
});
});
and client-side
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost'); // connec to server
socket.on('news', function (data) { // listen to news event raised by the server
console.log(data);
socket.emit('my other event', { my: 'data' }); // raise an event on the server
});
</script>
Alternatively, you can use a router function which calls some function on specific request from the client
var server = connect()
.use(function (req, res, next) {
var query;
var url_parts = url.parse(req.url, true);
query = url_parts.query;
if (req.method == 'GET') {
switch (url_parts.pathname) {
case '/somepath':
// do something
call_some_fn()
res.end();
break;
}
}
})
.listen(8080);
And fire AJAX request using JQuery
$.ajax({
type: 'get',
url: '/somepath',
success: function (data) {
// use data
}
})
Not exaclty sockets but a simple solution:
Can I suggest trying api-mount. It basically allows calling API as simple functions without having to think about AJAX requests, fetch, express, etc. Basically in server you do:
const ApiMount = apiMountFactory()
ApiMount.exposeApi(api)
"api" is basically an object of methods/functions that you are willing to call from your web application.
On the web application you then do this:
const api = mountApi({baseUrl: 'http://your-server.com:3000'})
Having done that you can call your API simply like this:
const result = await api.yourApiMethod()
Try it out. Hope it helps.
Related
I made some searches but didn't get exactly what I need. What I need is: I want to get some data generated in the client side javascript, make some manipulations on them in the server side Node.js, then return them back to javascript side. what is the simplest way to do this ?
Thanks in advance!
The simpliest way is to use socket.io
Your_project_path$ npm install socket.io
Server-side.js :
var http = require('http');
var io = require('socket.io');
httpServer = http.createServer();
httpServer.listen(8080);
var io = require('socket.io').listen(httpServer);
io.sockets.on('connection', function(socket) {
// Receive data
socket.on('my-data', function(data){
// Do something with your data
// Send modified data
socket.emit('my-modified-data', modified_data);
});
});
Client-side.js
var socket = io.connect('http://localhost:8080');
// Send your data
socket.emit('my-data', {
data-1 : 'something',
data-2 : 'something'
});
// Receive your modified data
socket.on('my-modified-data', function(modified-data){
// Do something with your new data
});
Client-side.html
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script src="client-side.js"></script>
REST.
In your client side you receive the data, modify it, send back to the server and to whatever you want.
I am trying to grasp using node express server and jQuery.ajax() in tandem. I have created a code repository with the following structure:
/
|-public
| |-index.html
|-server.js
My index page has the following JS snippet in it:
var successHandler = function (data, status, jqXHR) {
console.log('success')
};
var failHandler = function (jqXHR, status, errorThrown) {
console.log('fail')
};
var progressHandler = function () {
console.log('progress')
};
var ajaxConfig = {
url: 'http://localhost:4444/test',
type: 'GET'
};
$.ajax(ajaxConfig).then(successHandler, failHandler, progressHandler);
the server-side code is defined as such:
const express = require('express')
const app = express()
const sleep = require('sleep')
app.get('/test', function (req, res) {
console.log('/test method called!');
sleep.sleep(3);
res.status(202).send({"thing":"stuff"})
})
app.post('/test', function(req,res){
res.status(202).send('ok')
})
app.use(express.static('public'))
app.use(express.static('node_modules/jquery/dist'))
app.listen(4444, function () {
console.log('Running on localhost:4444!')
})
The thing that I want to accomplish is to get some hits on the progress handler, just to get it to write data in the console.
According to this page, I need to use the deffered.notify() method to trigger the handler but I have no idea how to get to the deffered object. I tried saving the return value of $.ajax() but that doesn't seem to have the notify() method since it is a jqXHR object.
It is my understanding that I need to have a progress handler defined on the server-side (the post handler for the /test route) that gets called to get to the current status of the pending task. Don't think making a new ajax request is the way to go, but I might be wrong. I have also found some articles that utilize the setTimeout method, My guess is that it gets used in order to repeatedly call the endpoint that gives status info.
Why isn't my client side updating automatically using socket.io and node.js?
My backend accepts JSON POST requests from PHP, then it emits the data to all connected devices.
My backend code
app.post('/', function (req, res) {
console.log(req.body);
subdata = req.body;
res.send('ok');
});
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('info', subdata);
});
Client side
<script>
var socket = io.connect('http://127.0.0.1:3000/');
socket.on('info', function (data) {
console.log(data);
});
</script>
That's because you only ever emit once when a new socket.io connection is made. If the app.post callback is called again, there's nothing to emit another message from socket.io.
You want to emit from within your app.post callback, and stop using global variables.
I have this socket.io server:
var io = require('C:\\Program files\\nodejs\\node_modules\\socket.io').listen(55555);
io.set('destroy upgrade', false);
io.sockets.on('connection', function (socket) {
socket.on('sayHello', function () {
console.log('Hello client!');
socket.emit('sayHello');
});
socket.on('disconnect', function () {
console.log('Goodbye!');
});
});
And I want to connect to the server using the WebSocket class like this:
var socket = new WebSocket('ws://localhost:55555');
I get the connection, but I want to know how can I call an event of the server, example: "sayHello", is that possible? or does Socket.IO use some kind of token in order to avoid spoofing? Thank you!
You should be able to use the socket.io-client module directly from node. It handles the socket.io protocol and everything for you, just like the browser, except in node.
I am attempting to use the subscribe function described here. However, when editing /assets/js/app.js, I am getting this error:
Uncaught ReferenceError: Room is not defined
So, I am not entirely sure why, but it cannot find my model. Here is my code:
Room.subscribe(req, [{id: "5278861ab9a0d2cd0e000001"}], function (response) {
console.log('subscribed?');
console.log(response);
});
and here is is in the context of app.js
(function (io) {
// as soon as this file is loaded, connect automatically,
var socket = io.connect();
if (typeof console !== 'undefined') {
log('Connecting to Sails.js...');
}
socket.on('connect', function socketConnected() {
// Listen for Comet messages from Sails
socket.on('message', function messageReceived(message) {
///////////////////////////////////////////////////////////
// Replace the following with your own custom logic
// to run when a new message arrives from the Sails.js
// server.
///////////////////////////////////////////////////////////
log('New comet message received :: ', message);
//////////////////////////////////////////////////////
});
///////////////////////////////////////////////////////////
// Here's where you'll want to add any custom logic for
// when the browser establishes its socket connection to
// the Sails.js server.
///////////////////////////////////////////////////////////
log(
'Socket is now connected and globally accessible as `socket`.\n' +
'e.g. to send a GET request to Sails, try \n' +
'`socket.get("/", function (response) ' +
'{ console.log(response); })`'
);
///////////////////////////////////////////////////////////
// This is the part I added:
Room.subscribe(req, [{id: "5278861ab9a0d2cd0e000001"}], function (response) {
console.log('subscribed?');
console.log(response);
});
//
});
// Expose connected `socket` instance globally so that it's easy
// to experiment with from the browser console while prototyping.
window.socket = socket;
// Simple log function to keep the example simple
function log () {
if (typeof console !== 'undefined') {
console.log.apply(console, arguments);
}
}
})(
Am I going about this the right way? should I be storing this directly in app.js?
To subscribe to a model instance, I use the following Real-Time Model Event pattern, some of which resides on the client and some on the server. Keep in mind the client can’t just subscribe itself- you have to send a request to the server letting it know that you’d like to be subscribed-- this is the only way to do it securely. (e.g. you might want to publish notifications with sensitive information-- you want to make sure a connected socket has permission to see that information before subscribing them to it.)
I’m going to use an example of an app with a User model. Let’s say I want to notify folks when existing users login.
Client-Side (Part I)
On the client-side, for simplicity, I’m going to use the existing app.js file in the /assets/js folder (or /assets/linker/js folder if you used the --linker switch when you built the app.)
To send my socket request to the server within assets/js/app.js, I’m going to use the socket.get() method. This method mimics the functionality of an AJAX “get” request (i.e. $.get() ) but uses sockets instead of HTTP. (FYI: You also have access to socket.post(), socket.put(), and socket.delete()).
The code would look something like this:
// Client-side (assets/js/app.js)
// This will run the `welcome()` action in `UserController.js` on the server-side.
//...
socket.on('connect', function socketConnected() {
console.log("This is from the connect: ", this.socket.sessionid);
socket.get(‘/user/welcome’, function gotResponse () {
// we don’t really care about the response
});
//...
Server-Side (Part I)
Over in the welcome() action in UserController.js, now we can actually subscribe this client (socket) to notifications using the User.subcribe() method.
// api/UserController.js
//...
welcome: function (req, res) {
// Get all of the users
User.find().exec(function (err, users) {
// Subscribe the requesting socket (e.g. req.socket) to all users (e.g. users)
User.subscribe(req.socket, users);
});
}
//...
Back on the client-side (Part II)...
I want the socket to ‘listen’ for messages I’m going to send it from the server. To do this I’ll use:
// Client-side (assets/js/app.js)
// This will run the `welcome()` action in `UserController.js` on the backend.
//...
socket.on('connect', function socketConnected() {
console.log("This is from the connect: ", this.socket.sessionid);
socket.on('message', function notificationReceivedFromServer ( message ) {
// e.g. message ===
// {
// data: { name: ‘Roger Rabbit’},
// id: 13,
// verb: ‘update’
// }
});
socket.get(‘/user/welcome’, function gotResponse () {
// we don’t really care about the response
});
// ...
Back on the server-side (Part II)...
Finally, I’ll start sending out messages, server-side, by using: User.publishUpdate(id);
// api/SessionController.js
//...
// User session is created
create: function(req, res, next) {
User.findOneByEmail(req.param('email'), function foundUser(err, user) {
if (err) return next(err);
// Authenticate the user using the existing encrypted password...
// If authenticated log the user in...
// Inform subscribed sockets that this user logged in
User.publishUpdate(user.id, {
loggedIn: true,
id: user.id,
name: user.name,
action: ' has logged in.'
});
});
}
//...
You can also check out Building a Sails Application: Ep21 - Integrating socket.io and sails with custom controller actions using Real Time Model Events for more information.