Making a game w/ Spark Core, better way than post request?

Hi all,

I am planning on making a game using my Spark Core, but am not sure the best way to go about it. Originally I was planning on making a webpage with several buttons and when clicked would send an ajax post to the spark core where it would react accordingly. However, I am worried that this method may result in delay, a situation I am trying to avoid. Do you guys have any other suggestions on how to handle this?

Hi @lbruder,

If you can, direct TCP/UDP sockets / communication on a local network will always be the fastest. If you’re doing a POST request and you’re not on the same network, you can send it to the API and do a spark function instead, which might save you some processing time. A POST request directly to the core might be a lot of overhead, unless that’s something Webduino can do?

There are lots of great examples for controlling cores quickly over the local network, one popular one is VoodooSpark - https://github.com/voodootikigod/voodoospark

I hope that helps!

Thanks!
David

1 Like

what do you think the best way to do a tcp connection would be? a cgi script possibly? not too familiar with the web side of things, more familiar with the embedded side… it will be on the local network

Maybe if I explained it better it would help… I want to make a website hosted on my rpi where I can have a website with a simple left and right button. When these are clicked, I want to send some kind of AJAX message to where I can get a message like “Player 1 : Left” to the Spark Core with the least amount of latency. I’ve looked at Webduino a bit, but I’m not sure if it’s exactly what I’m looking for

@lbruder, have you considered using calling a Spark.function() from your website instead of sending an AJAX message?

@peekay123 would you mind elaborating? originally i was planning on making an ajax post through jquery where it would call my function, but im not sure if this will be fast enough… i do have a tcp client/server i wrote for my rpi to where i could send messages through that, but not sure exactly how i would do that through the website. maybe a cgi script?

@lbruder, I may or may not be a solution but here is the documentation:

http://docs.spark.io/firmware/#data-and-control-spark-function

In theory, if you made the AJAX request directly to the Spark Cloud (without any sort of proxy to hide the access token), it would take one less hop than if you sent that AJAX request to the server hosting the web page (the RPi?) which then proxies the request onto the Spark Cloud. The Spark Cloud still has to send a request (for Spark.variable() or Spark.function()) to your Core and back through the whole round trip again. The whole thing could take a second or two to complete.

If you ran it off a local cloud on the same network, then you’ll eliminate the dozens of hops across whatever networks it takes to get from your browser to your Core and back again. If they’re on the same subnet or same local network, a local cloud request would take much less time.

If that’s still too slow, you’ll have to communicate from your web browser directly to your Core. There are a few options that are web-browser friendly, but they may not be easy to implement:

  • Plain GET/POST HTTP server (easiest)
  • PubSub server using bayeux protocol (like CometD)
  • Web sockets
  • WebRTC server (still pretty new)

I know the HTTP server can be done on the Core now, and there are a couple of libraries floating around that can get you up and running quick. The other three are options that are browser-friendly but don’t have any sort of library yet (that I know of), so that implementation would be entirely up to you.

If you have the resources like an extra computer or Raspberry Pi (or similar), I would try the local cloud first since it would be similar to what you’re already used to using. If that doesn’t work, try running an HTTP server directly on the Core.

2 Likes

@wgbartley thanks for the response! I do have the capabilities/would prefer to host the cloud locally on my RPi. Let’s say I go this route, what would the url be for my spark function call?

@lbruder The problem you have is not on the Spark but on your web browser side to create TCP or UDP sockets.

If you can manage to spend a couple of hours on learning node.js then you could have:

  • Node HTTP Server on the RPi for the website (http, express, socket libraries)
  • This handles the user-interface
  • Node TCP/UDP Client on the RPi to communicate with the Spark (net, dgram libraries)
  • This handles communication to the spark when there is user action
  • TCP/UDP Server on the Spark
  • This handles receiving messages from the node server.

If you can keep the TCP Connection open for as long as your game lasts, then you would have almost next to nothing latency, but its a challenge running a TCP server on the spark if you have too many clients connect to it.

If you use UDP server on the spark, you will “most likely” have a consistently low latency, but there is a good chance that you will have packet loss, which you can counter by sending multiple duplicate packets (not a great practice). UDP server implementation on the spark is fairly simple and almost always without issues.

@nitred Thanks for the response! Let’s say I go the node.js HTTP server route. How would I be able to respond to a button click without loading a new page? Would this be doable via C? I have much more experience with writing an HTTP server and have already written a threaded TCP client in C, but am not sure how to do the web side of things… I want to be able to use an iphone as a game controller for each person, but want to avoid reloading the web page each time incase a button has to be pressed multiple times in one second

Hi @lbruder @nitred @wgbartley @Dave I saw this old post and wonder if anything new has come from it. @peekay123 has helped me get something similar at:

My time lag per command sent to the spark is about 55-77 ms whereas function calls to the cloud seems to be between 300-1200ms (https://github.com/hpssjellis/spark-core-web-page-html-control). I am still interested in getting voodoospark working over the web. Any recent ideas?

Hi @rocksetta,

I think the benefit of something like voodoospark is that you’re skipping a roundtrip out to the cloud and back, which depending on your internet connection can save you a lot of latency if you’re doing something like driving a robot / game. I would recommend using the cloud connection to advertise an IP address / socket, and send messages directly that way. I think voodoospark essentially does this, it just requires you’re on the same wifi network as your device.

Thanks!
David

I need better access than using the same WiFi. I noticed in the Photon Docs that you can obtain a public IP. Do you think we can then use VoodooSpark over the internet not just on our local network.

http://docs.particle.io/photon/firmware/#get-public-ip

GET PUBLIC IP
Using this feature, the device can programmatically know its own public IP address.

Looks like this might work on the Core as well

.

// Open a serial terminal and see the IP address printed out
void handler(const char *topic, const char *data) {
    Serial.println("received " + String(topic) + ": " + String(data));
}

void setup() {
    Serial.begin(115200);
    for(int i=0;i<5;i++) {
        Serial.println("waiting... " + String(5 - i));
        delay(1000);
    }

    Spark.subscribe("spark/", handler);
    Spark.publish("spark/device/ip");
}

Hi @rocksetta

This feature works today-you can use publish and subscribe to get your router’s public IP address.

Then what? If you have an open port on the router that your Core/Photon is listen to, you can connect. But for some people that will not be an option due to IT or security constraints.

A better plan might be to connect from the Core/Photon to the other host since most routers are not configured to block outgoing requests, but this requires a server on the web that is listening for your device.

1 Like

Good idea with the external (nodejs) server, I think I will try that. What might be easiest is to be able to assign the local IP but I think WiFi.localIP(); is readonly.

On Ubuntu linux assigning a local IP looks like this:

iface eth0 inet static
address 192.168.0.101
gateway 192.168.0.1
netmask 255.255.255.0
dns-nameservers 8.8.8.8 8.8.4.4

Do you @bko know if the local IP can be assigned? At home I can match my MAC address to an IP and then open a port (port forward) for that IP, but at work I already have a local IP assigned to an external IP with several open ports. Any suggestions how to use that.

Hi @rocksetta

The easiest way is to make your router always give out the same IP to your core based on its MAC address. Some people call this “static dynamic” addressing but that is oxymoronic to my ears.

There is another way that forces that core’s IP address but a few people have had trouble using it. This would be a true static address. See this topic for ideas:

1 Like

@bko The external server is a good idea, do you know of anyone trying it? Any ideas @peekay123 ? I have seen some really easy Nodejs chat servers that work really well and fast. If the core or photon could be a TCP client connected to a chat server that could be hacked to have buttons instead of typing commands then this might be comparable to voodooSpark but internet capable not confined to a local network.

If you login to cloud9 https://c9.io the default Nodejs demo program is a chat server. If the core TCP client can receive any text from that server the problem would almost be solved. Anyone familiar with chat servers?

Oops, on second thought this will probably never work. I need a Cross Domain chat server that browsers can log into, and probably better if the core TCP client can leave the connection open so that we don’t have to do polling.