I am using a simple node.js server to broadcast messages:
var ws = require('websocket.io');
var server = ws.listen(3000);
server.on('connection', function(socket) {
socket.on('message', function(data) {
server.clients.forEach(function(client) {
client.send(data);
});
});
});
The client is written in c++ (cocos2dx framework) and it's working like this:
_websocket = new WebSocket();
_websocket->init(*this, "ws://localhost:3000");
....
_websocket->send(message);
When I measure the latency by sending something to the server and waiting for the response: it's around 80-100ms. The node.js server runs on localhost and I would expect the ping to be around 0-10ms max.
Do you know the reason why the ping is so high? Do I have to flush something or is something wrong with the server setup?
Thanks!
Related
I'm writing a program that required connecting to a Web Server using the Web Socket Channel package. I am following the guide https://flutter.dev/docs/cookbook/networking/web-sockets to connect to an AWS Server. The link is something like this:
wss://xxxxxxx.execute-api.ap-southeast-1.amazonaws.com/dev/
Using the package I was able to connect and get the connectionState.waiting, but I cannot seem to listen to any data from the server nor send data to the server. For the data send, the format is below:
Map message = {
"action": 'subscribe',
"channel": 'contentTest',
};
channel.sink.add(jsonEncode(message));
The rest of my code is similar to the guide, however the server does not seem to receive any data and neither can my client. Can anyone share a working example for above problem? Thank you in advance.
I have a working example to share, you can see how the connection is done and the message is sent, this example is using the WebSocket class in dart:io. When I was coding this I had some issues with Web Socket Channel, can't remember why, so I opted for Dart WebSocket class.
Future<WatchResponse> WatchCollection(
CollectionRequest collectionRequest, String token) async {
try {
WebSocket ws = await WebSocket.connect(
"ws://${this.authority}/gapi/collection/watch?token=$token");
if (ws.readyState == WebSocket.open) {
ws.add(jsonEncode(collectionRequest.toMap()));
return WatchResponse(ok: true, streamSubscription: ws.listen(null));
}
} on WebSocketException catch (err) {
return WatchResponse(ok: false, webSocketExecption: err);
}
return WatchResponse(ok: false, webSocketExecption: null);
}
I am running my nodejs application on google cloudrun. My application connects to google memorystore redis. Every few mins am getting the following error
Error: read Connection Reset
Followed by
AbortError: Redis connection lost and command aborted. It might have been processed.
Please help what am I missing?
My nodejs code
const redis = require('redis')
const redisClient = redis.createClient({host:'xxx', port: 6379})
redisClient.on('error, function (err) {
console.log(err)
}
const data = await redisClient.getExAsync('key')
Use "setInterval" function in order to invoke Redis operation every minute.
async function RedisKA() {
client.get("key2", (err, reply) => {
console.log(`${kaCount} redis keep `);
});
}
let updateIntervalId = setInterval(RedisKA, 60000);
If you want to avoid the request timeout on the Cloud Run side, which is 5 minutes by default then set your value based on your requirement.
The issue may be caused due a socket time out. This is expected to happen when there is no activity for a period of time.
This could be avoided by periodically executing any command on the connection, for example one command per minute, so it will keep the socket alive and will not abort the connection.
I'm trying to execute command in a contianer (in a Kubernetes POD on GKE with kubernetes 1.1.2).
Reading documentation I understood that I can use GET or POST query to open websocket connection on API endpoint to execute command. When I use GET, it does not work completly, returns error. When I try to use POST, something like that could work probably (but it's not):
curl 'https://admin:xxx#IP/api/v1/namespaces/default/pods/hello-whue1/exec?stdout=1&stderr=1&command=ls' -H "Connection: upgrade" -k -X POST -H 'Upgrade: websocket'
repsponse for that is
unable to upgrade: missing upgrade headers in request: http.Header{"User-Agent":[]string{"curl/7.44.0"}, "Content-Length":[]string{"0"}, "Accept":[]string{"*/*"}, "Authorization":[]string{"Basic xxx=="}, "Connection":[]string{"upgrade"}, "Upgrade":[]string{"websocket"}}
Looks like that should be enough to upgrade post request and start using websocket streams, right? What I'm missing?
I was also pointed that opening websocket with POST is probably violation of websocket protocol (only GET should work?).
Also
You'll probably have the best time using the Kubernetes client library, which is the same code the Kubectl uses, but if for some reason that isn't an option, than my best suggestion is to look through the client library's code for executing remote commands and seeing what headers it sets.
Use websocket client it's work.
In my local kuberenetes cluster, the connection metadata like this:
ApiServer = "172.21.1.11:8080"
Namespace = "default"
PodName = "my-nginx-3855515330-l1uqk"
ContainerName = "my-nginx"
Commands = "/bin/bash"
the connect url:
"ws://172.21.1.11:8080/api/v1/namespaces/default/pods/my-nginx-3855515330-l1uqk/exec?container=my-nginx&stdin=1&stdout=1&stderr=1&tty=1&command=%2Fbin%2Fbash"
On maxos, a wsclient CLI tool: wscat, you can use it as a test tool:
You can access the websocket example: "https://github.com/lth2015/container-terminal"
You can using a websocket client to exec into a pod, a quick demo.
javascript code shows how to connect to kubernetes:
<script type="text/javascript">
angular.module('exampleApp', ['kubernetesUI'])
.config(function(kubernetesContainerSocketProvider) {
kubernetesContainerSocketProvider.WebSocketFactory = "CustomWebSockets";
})
.run(function($rootScope) {
$rootScope.baseUrl = "ws://localhost:8080";
$rootScope.selfLink = "/api/v1/namespaces/default/pods/my-nginx-3855515330-l1uqk";
$rootScope.containerName = "my-nginx";
$rootScope.accessToken = "";
$rootScope.preventSocket = true;
})
/* Our custom WebSocket factory adapts the url */
.factory("CustomWebSockets", function($rootScope) {
return function CustomWebSocket(url, protocols) {
url = $rootScope.baseUrl + url;
if ($rootScope.accessToken)
url += "&access_token=" + $rootScope.accessToken;
return new WebSocket(url, protocols);
};
});
</script>
you can test it in other language.
Gives In my windows Phone 8.1 application and using MvvmLight ,
I am sending two doubles to my web service, it works on Emulator in the following code;
DispatcherHelper.CheckBeginInvokeOnUI(async () =>
{
Geolocator geo = new Geolocator();
Geoposition pos = await geo.GetGeopositionAsync();
HttpClient client = new HttpClient();
var request = await client.GetAsync(new Uri("http://..+double a,+ double b, UriKind.RelativeOrAbsolute));
var response = await request.Content.ReadAsStringAsync();
BranchList = JsonConvert.DeserializeObject<List<Branch>>(response);
}
than, I am switch on my phone's GPS and Wifi but it gives bad request.
1) Did you look at your web service to check if you find a difference between the request from emulator and real device?
2) Disable carrier on real phone and try with network, and check again on webservice side too, to see if you find a difference in the request?
3) Another way, with Wireshark you can check your request between real device and emulator (but is more work and complicated than 1 and 2 )
I'm trying to figure out how to shut down an instance of Express. Basically, I want the inverse of the .listen(port) call - how do I get an Express server to STOP listening, release the port, and shutdown cleanly?
I know this seems like it might be a strange query, so here's the context; maybe there's another way to approach this and I'm thinking about it the wrong way. I'm trying to setup a testing framework for my socket.io/nodejs app. It's a single-page app, so in my testing scripts (I'm using Mocha, but that doesn't really matter) I want to be able to start up the server, run tests against it, and then shut the server down. I can get around this by assuming that either the server is turned on before the test starts or by having one of the tests start the server and having every subsequent test assume it's up, but that's really messy. I would much prefer to have each test file start a server instance with the appropriate settings and then shut that instance down when the tests are over. That means there's no weird dependencies to running the test and everything is clean. It also means I can do startup/shutdown testing.
So, any advice about how to do this? I've thought about manually triggering exceptions to bring it down, but that seems messy. I've dug through Express docs and source, but can't seem to find any method that will shut down the server. There might also be something in socket.io for this, but since the socket server is just attached to the Express server, I think this needs to happen at the express layer.
Things have changed because the express server no longer inherits from the node http server. Fortunately, app.listen returns the server instance.
var server = app.listen(3000);
// listen for an event
var handler = function() {
server.close();
};
Use app.close(). Full example:
var app = require('express').createServer();
app.get('/', function(req, res){
res.send('hello world');
});
app.get('/quit', function(req,res) {
res.send('closing..');
app.close();
});
app.listen(3000);
Call app.close() inside the callback when tests have ended. But remember that the process is still running(though it is not listening anymore).
If after this, you need to end the process, then call process.exit(0).
Links:
app.close: http://nodejs.org/docs/latest/api/http.html#server.close (same applies for)
process.exit:
http://nodejs.org/docs/latest/api/process.html#process.exit
//... some stuff
var server = app.listen(3000);
server.close();
I have answered a variation of "how to terminate a HTTP server" many times on different node.js support channels. Unfortunately, I couldn't recommend any of the existing libraries because they are lacking in one or another way. I have since put together a package that (I believe) is handling all the cases expected of graceful HTTP server termination.
https://github.com/gajus/http-terminator
The main benefit of http-terminator is that:
it does not monkey-patch Node.js API
it immediately destroys all sockets without an attached HTTP request
it allows graceful timeout to sockets with ongoing HTTP requests
it properly handles HTTPS connections
it informs connections using keep-alive that server is shutting down by setting a connection: close header
it does not terminate the Node.js process
Usage with Express.js:
import express from 'express';
import {
createHttpTerminator,
} from 'http-terminator';
const app = express();
const server = app.listen();
const httpTerminator = createHttpTerminator({
server,
});
await httpTerminator.terminate();
More recent version of express support this solution:
const server = app.listen(port);
const shutdown = () => {
server.close();
}
You can easily do this by writing a bash script to start the server, run the tests, and stop the server. This has the advantage of allowing you to alias to that script to run all your tests quickly and easily.
I use such scripts for my entire continuous deployment process. You should look at Jon Rohan's Dead Simple Git Workflow for some insight on this.