Is it possible to do this? Or perhaps, the question I should ask, is it feasible?
Or would it be better off to just stick with Java/Android front-end and Java back end server?
Would a node js backend be practical for multiplayer games? Or perhaps just for web applications that do not require much
And if it (java-nodejs) is practical for multiplayer games, how would one go about getting a java client to be able to communicate with a node js server?
If you're building an API, you don't have to worry about the language in wich you write it, the way to communicate with it will remain the same (UDP/HTTP/WS request).
Nevertheless, you're creating a multiplayer game, so you will need good performance for the back-end.
NodeJS is good, very good ! Erlang is better ;)
Yes, it is feasible. Node is very efficient and fast in handling requests. Since it works on a event based model its great for server side.
If you are working with Android and NodeJs as the server side I can help with this:
You can use Volley in Android to make a json POST or GET request.
And for the NODE JS you can use node's built-in http module to create a simple HTTP server and then receive data from the req object.
const http=require('http');
const stringDecoder=require('string_decoder').StringDecoder;
var httpServer=http.createServer(function(req,res){
unifinedServer(req,res);
});
//Just another method.
var unifinedServer=function(req,res){
var decoder=new stringDecoder('utf-8');
var buffer='';
//reading the post data.
req.on('data',function(data){
buffer+=decoder.write(data);
});
//Reading of data is completed.
req.on('end',function(){
buffer+=decoder.end();
// Do what ever you want to do with the POST data.
});
}
//The Server is listening on a specific port.
httpServer.listen(7000,function(){
console.log("Server is now listening on Port..."+7000);
});
For the Android Code you can do this with volley:
String url = "http://example.com";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.POST, url, postJsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mTextView.setText("Response: " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
Related
I have a Java Spring Application with a Tomcat server that listen on kafka topic. I want to display all messages in a real-time mode on the web page. Therefore, when a kafka messages is arrived in the backend I want to see it on my web page. I don't know a good approach to push kafka message directly to the front-end and display it on web page. Is someone could help my with a solution and some examples that could help? Thanks!
I have implemented a system like this in Java for my last employer, albeit not with Spring/Tomcat. It was consuming messages from Kafka and serving them on a web socket to be displayed in the browser. The approach I followed was to use akka-stream-kafka and akka-http for web-socket support. The benefit of that is both are based on akka-streams which makes it an easy fit for streaming data.
While you can embed akka-http in your spring app running inside tomcat, it may not feel the most natural choice any more as spring framework already has its own support for both kafka and websockets. However, if you're not familiar with either, then jumping on the akka approach may be easiest and the core logic goes along these lines (I can't share the code from work so have just put this together from the examples in the docs, not tested):
public Route createRoute(ActorSystem system) {
return path("ws", () -> {
ConsumerSettings<byte[], String> consumerSettings = ConsumerSettings.create(system, new ByteArrayDeserializer(), new StringDeserializer())
.withBootstrapServers("localhost:9092")
.withGroupId(UUID.randomUUID().toString()) //this is so that each client gets all messages. To be able to resume from where a client left off in case of disconnects, you can generate in on the client side and pass in the request
.withProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest")
return handleWebSocketMessages(
Flow.fromSinkAndSourceCoupled(
Sink.ignore(),
Consumer.committableSource(consumerSettings, Subscriptions.topics("topic1"))
.map(msg -> TextMessage.create(msg.record().value()))
)
);
}
}
To expose this route you can follow the minimalistic example, the only difference being the route you define needs the ActorSystem:
final Http http = Http.get(system);
final ActorMaterializer materializer = ActorMaterializer.create(system);
final Flow<HttpRequest, HttpResponse, NotUsed> routeFlow = createRoute(system).flow(system, materializer);
final CompletionStage<ServerBinding> binding = http.bindAndHandle(routeFlow,
ConnectHttp.toHost("localhost", 8080), materializer);
Once you have your messages published to the websocket, the front end will code will of course depend on your UI framework of choice, the simplest code to consume ws messages from javascript is:
this.connection = new WebSocket('ws://url-to-your-ws-endpoint');
this.connection.onmessage = evt => {
// display the message
To easily display the message in the UI, you want the format to be something convenient, like JSON. If your Kafka messages are not JSON already, that's where the Deserializers in the first snippet come in, you can convert it to a convenient JSON string in the Deserializer or do it later on in the .map() called on the Source object.
Alternatively, if polling is an option you can also consider using the off-the-shelf Kafka Rest Proxy, then you only need to build the front-end.
I have a Node JS chat server that uses simple JSON messaging to send commands and chat messages between clients. It works great, but I know from previous experience that it is essential to provide, in the least, an end-of-file or end-of-transmission tag.
Because Node has done so much of the server and networking work for me, I don't want to re-invent an existing wheel, but I can't find a great resource about building up Node buffers.
Given a client connects
net.createServer(function(socket){
socket.setEncoding("utf8");
var client = self.clientManager.create(socket);
self._attachDefaultHandlers(client);
}).listen(this.settings.port);
And handlers are attached
_attachDefaultHandlers(client){
client.socket.on('data', function(data){
});
client.socket.on('end', function(){
});
client.socket.on('close', function(){
});
return this;
}
How can I build up a buffer to know that a message from the client is complete in regards to the .on('data') event? And who is in charge of this buffer - the spawned client or the server? Who manages it?
I have a school project where i need to create an instant webbased messageing system.
Ive looked into PHP sockets to complete this task PHP socket manual
From these im starting to see a pattern. As you well know PHP can only run once (from top to bottom) and from these examples i can see that a while loop is what makes the socket listen for new connections. (meaning the php script never stops) these examples the echo the output of the socket.
as far as i can see this is great if you just want a plain site.
However this is not the case. I want to build this application using JavaScript to "ask" the socket if there is any new messages and if there is then render the messages accordingly.
Since im very new to PHP sockets im not sure if this should be done purely by PHP or if it is possible to use JavaScript to listen to the socket (via Ajax) and then print the output as a JSON?
I recommend you to use a third party library (well, an recommend you again this library: cboden/ratchet). Read its tutorials and you will have a cleaner look at how to communicate between browsers ans servers using WebSocket protocol.
The server is absolutely able to be implemented with pure PHP!
In general for push based notifications the protocol you will want (which only works with newer browsers) is WebSockets.
There are a variety of libraries and services which can do this for you:
Pusher, is an online service which can integrate with a variety of languages to give you real time functionality. https://pusher.com/
In JavaScript only, and if you have node you should look at socket.io : http://socket.io/
In .NET land, there is SignalR which is fantastic http://signalr.net/
Not only is it possible to do with PHP but it's also trivial with Thruway. Thruway is a WAMPv2 PHP client/router that uses Ratchet for the Websocket transport. WAMP gives you Sub/Pub and RPC over WebSockets.
You would need to create a simple php router and start it from the command line. Something like this:
<?php
require 'vendor\autoload.php';
use Thruway\Peer\Router;
use Thruway\Transport\RatchetTransportProvider;
$router = new Router();
$transportProvider = new RatchetTransportProvider("127.0.0.1", 9090);
$router->addTransportProvider($transportProvider);
Then on the client, use AutobahnJS or if you're using angular, you can use angular-wamp.
If you still have questions, I'll work up a simple chat example.
I actually used a PHP based websocket and adapted it. I can work both ways if you want. You can store the messages sent to the websocket in an Array or even let them be saved into a database. The client can ask for new messages:
look at this code:
function createConnectionToWebSocket(connection)
{
var host = "ws://[ip of server]:9000/echobot"; // SET THIS TO YOUR SERVER --> 9000 is the port used by websockets.
try {
socket = new WebSocket(host);
console.log('WebSocket - status '+socket.readyState);
socket.onopen = function(msg) {
console.log("Welcome - status "+this.readyState);
};
socket.onmessage = function(msg) {
messageHandlerSocket(msg.data);
};
socket.onclose = function(msg) {
console.log("Disconnected - status "+this.readyState);
if (msg && !msg.wasClean && msg.code == 1006)
{
}
};
socket.onerror = function(msg) {
};
}
catch(ex){
console.log(ex);
}
}
function messageHandlerSocket(msg)
{
//all messages will be send in JSON
var msg = JSON.parse(msg)
//received JSON and check the type. Type is message
switch (msg.type)
{
case "messages" :
//code when the webserver sends back the messages.
break;
}
}
socket.send(JSON.stringify({"type" : "retrievemessages", "user" : user.id}));
Socket.send allows you to send data to the PHP server. I send JSON and parse this on the server. Based on the type argument I let the PHP server send data back to the corresponding user.
I extend this webserver I found on Github.
Run the webserver via a bat-file.
#ECHO OFF
ECHO STARTING WEBSERVER
ECHO USING [dir to php dir]\php\php.exe
#ECHO OFF
START "WEBSOCKET" /wait /B "[dir to php dir]\php\v5.6\php.exe" -f [path to your websocket.php]
I have been experimenting with Node.js on my machine for a little while and I have found my knowledge of HTTP requests, XHR objects, and the like quite lacking. So the main thing that's been nagging at me while using Node is that I can't seem to understand how to communicate from the client to the server (other than simple GET requests) and vice versa. What brings me to this question is my recent project, which is a simple 2 player chess game (no AI opponents).
What I want to do is to be able to send the game board data (a JSON string) to the server and have it save the data to a file. I understand how to get the file contents using an XHR object on the client-side. I also understand how to use Node's fs module to create and read files on the server-side. What I don't understand is how to use the XHR object to send the string to the server and have Node process and save it into a file. Is it even possible to call server-side code using client-side code in this way? Is trying to send an argument through a XHR object to the server an incorrect way of doing this?
If what I have asked is too broad of a topic to answer, I would also be open to links and books on the topic of server and client communication.
Expanding on SLaks answer a little:
Assuming you're using jQuery on the client and express on the server (both are useful frameworks to avoid reinventing low-level stuff), you could do something like this.
Client
$.ajax({
type: "POST",
url: "http://www.yourserver.com:3000/some/path",
data: { ...chessdatahere... }
}).done(function(msg) {
alert("Data Saved: " + msg);
});
Server
var fs = require('fs');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/some/path', function(req, res) {
fs.writeFile('filename', res.body, function(err) {
if (err) {
res.send('Something when wrong');
} else {
res.send('Saved!');
}
})
});
app.listen(3000);
(Note that the code has not been tested, but it should show the general idea at least).
You can can use XHR to send an HTTP request with (eg) JSON data in the POST payload.
You can then write server-side Node.js code that handles this request, reads the payload, and does whatever you want with the data.
When you have a RESTful server which only responds with JSON by fetching some information from the database, and then you have a client-side application, such as Backbone, Ember or Angular, from which side do you test an application?
Do I need two tests - one set for back-end testing and another set for front-end testing?
The reason I ask is testing REST API by itself is kind of difficult. Consider this code example (using Mocha, Supertest, Express):
var request = require('supertest');
var should = require('chai').should();
var app = require('../app');
describe('GET /api/v1/people/:id', function() {
it('should respond with a single person instance', function(done) {
request(app)
.get('/api/v1/people/:id')
.expect(200)
.end(function(err, res) {
var json = res.body;
json.should.have.property('name');
done();
});
});
});
Notice that :id in the url? That's an ObjectId of a specific person. How do I know what to pass there? I haven't even looked into the database at this point. Does that I mean I need to import Person model, connect to database and do queries from within the tests? Maybe I should just move my entire app.js into tests? (sarcasm :P). That's a lot of coupling. Dependency on mongoose alone means I need to have MongoDB running locally in order to run this test. I looked into sinon.js, but I am not sure if it's applicable here. There weren't many examples on how to stub mongoose.
I am just curious how do people test these kinds of applications?
Have you tried using mongoose-model-stub in your server-side test? It will free you from having to remember or hardcode database info for your tests.
As for testing the client side, your "webapp" is basically two apps: a server API and a client-side frontend. You want tests for both ideally. You already know how to test your server. On the client you would test your methods using stubbed out "responses" (basically fake json strings that look like what your web service spits out) from your API. These don't have to be live urls; rather it's probably best if they're just static files that you can edit as needed.
I would use nock..https://github.com/pgte/nock
What you want to test is the code you have written for your route.
So what you do is, create a response that will be sent when the end point is hit.
Basically its a fake server..
Something like this..
Your actual method..
request({
method: "GET",
url: "http://sampleserver.com/account"
}, function(err, res, data){
if (err) {
done(err);
} else {
return done(null,data);
}
});
Then..
var nockObj = nock("http://sampleserver.com")
.get("/account")
.reply(200,mockData.arrayOfObjects);
//your assertions here..
This way you don't alter the functionality of your code.. Its like saying.. instead of hitting the live server..hit this fake server and get mock data. All you have to do is make sure your mock data is in sync with the expected data..