Streaming example using HTTP/2 - http2

I am looking to write a data recorder that uses HTTP/2 to stream data from clients to the recorder, as well as retrieve data from a recorder via streams.
Looking at the JavaScript API for HTTP/2, it's not obvious to me how to keep a stream open and to exchange bidirectional traffic until some trigger event ends the recording.
Hence, I'm seeking examples (preferably JavaScript) of how to perform bidirectional exchanges for long lasting connections.

The following code snippets form the basis of what I am trying to achieve.
Server:
import http2 from 'http2'
import fs from 'fs'
// Private key and public certificate for access
const options = {
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('public-cert.pem'),
};
// Creating and initializing server
const server = http2.createServer(options);
server.on('error', (error) => {
console.log('Error: ' + error);
});
server.on('stream', (stream, requestHeaders) => {
stream.respond({
':status': 200,
'content-type': 'text/plain'
});
stream.on('data', (data) => {
console.log('Received data: ' + data.toString());
stream.write(data); // echo received data back
});
stream.on('close', () => {
console.log('stream closed');
});
stream.on('end', () => {
console.log('stream end');
});
});
server.listen(8000);
Client:
I originally specified the Content_Length in the POST request, but this produced errors, when attempting to send more than one message to the server.
import http2 from 'http2'
let x = 0;
// Creating and initializing client
const client = http2.connect('http://localhost:8000');
console.log("Client connected");
const msg1 = 'message 1';
let req = client.request({
':method': 'POST',
':path': '/',
'Content-Type': 'text/plain',
});
req.on('response', (responseHeaders, flags) => {
console.log("status : " + responseHeaders[":status"]);
});
req.write(msg1);
req.on('data', (data) => {
console.log('Received: %s ', data.toString());
req.write("aaa" + x.toString());
x = x + 1;
if (x > 10) {
req.close();
}
});
req.on('end', () => {
client.close(() => {
console.log("client closed");
})
});
req.on('error', (error) => {
console.log(error);
})
The output on the server is:
Received data: message 1
Received data: aaa0
Received data: aaa1
Received data: aaa2
Received data: aaa3
Received data: aaa4
Received data: aaa5
Received data: aaa6
Received data: aaa7
Received data: aaa8
Received data: aaa9
Received data: aaa10
stream end
stream closed
The output on the client is:
Client connected
status : 200
Received: message 1
Received: aaa0
Received: aaa1
Received: aaa2
Received: aaa3
Received: aaa4
Received: aaa5
Received: aaa6
Received: aaa7
Received: aaa8
Received: aaa9
client closed

Related

How can I convert this Ajax query to http client request in Angular 8?

I have a request in ajax, like this:
var data = {
REQUEST: 'GetFeatureInfo',
SERVICE: 'WMS',
VERSION: '1.1.1',
LAYERS: layerName,
STYLES: '',
FORMAT: 'image/png',
INFO_FORMAT:'application/json',
BGCOLOR: '0xFFFFFF',
TRANSPARENT: 'TRUE',
SRS: 'EPSG:' + mapSRID,
BBOX: xmin + "," + ymin + "," + xmax + "," + ymax,
WIDTH: map.width,
HEIGHT: map.height,
QUERY_LAYERS: layerName,
X: screenPoint.x.toFixed(0),
Y: screenPoint.y.toFixed(0)
};
$.ajax({
type: 'GET',
url: url,
data: data,
dataType: "application/json",
complete: function (data) {
callBack(data);
}
});
}
I want to convert to angular by using http client get method. How can I do that.
My solution but reponse: ok: false
getInfo() {
const params = {
SERVICE: 'WMS',
VERSION: '1.1.1',
...
};
this.http.get<any>('http://localhost:8080/geoserver/topp/wms', params).subscribe(data => {
console.log(data);
});
}
The response:
status: 200
statusText: "OK"
url: "http://localhost:8080/geoserver/topp/wms?SERVICE=WMS&VERSION=1.1.1&EQUEST=GetFeatureInfo&FORMAT=image/png&TRANSPARENT=true&QUERY_LAYERS=topp:states&LAYERS=topp:states&exceptions=application/vnd.ogc.se_inimage&INFO_FORMAT=text/html&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG:4326&STYLES=&WIDTH=101&HEIGHT=101&BBOX=-113.8623046875,42.4072265625,-104.9853515625,51.2841796875"
ok: false
To more clear, I'm want to convert URL get request to http client get method request in Angular 8:
http://localhost:8080/geoserver/wms?service=wms&version=1.1.1&request=GetCapabilities
Inject HttpClient to in your service.
this.http.post(url , data).subscribe(response => {
console.log(response);
}) //post request if you have to send data
this.http.get(url).subscribe(response => {
console.log(response);
})//get if you want data
Ajax internally append data you send with the request to the url string. So in order to do that using angular, you need to use HttpParams
let params = new HttpParams().set("paramName",paramValue).set("paramName2", paramValue2); //Create new HttpParams
this.http.get(url, {headers: headers, params: params});
In your data you have EQUEST instead of REQUEST

Network Request failed while sending image to server with react native

i want to send image to a server and getting the result with a json format but the application returns a Network Request failed error
react native 0.6 using genymotion as emulator
i tried RNFetchblob but the result take a long time to get response (5 min )
also i tried axios but it response with empty data with 200 ok
this is the function that import the image
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
and this method that sends the image
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.avatarSource , name:'file.jpeg'});
fetch(url, {
method: 'POST',
body:UplodedFile
})
.then(response => response.json())
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});
i expect json format
ScreenShot here
can you change your code like this?
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
pickerResponse: response,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.pickerResponse.path , name:'file.jpeg'});
axios({
method: "post",
url: url,
data: UplodedFile
})
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});

Receiving Flux SSE in Angular 5

I have succesfully implemented this mechanism in my application:
https://vividcode.io/Spring-5-WebFlux-with-Server-Sent-Events/
I can receive events with curl every second, as shown in the example.
My problem is: I cannot receive these events in Angular 5. I have tried many things. Currently my service code looks like this:
public getMigrationProgress(processName: string): Observable<any> {
let headers: HttpHeaders = new HttpHeaders();
headers = headers.append('X-Authorization', this._sessionService.getAuthToken());
headers = headers.append('accept', 'text/event-stream');
let url = config.restApi.url + this.getResource() + '/' + processName;
return Observable.create(observer => {
let eventSource = new EventSourcePolyfill(url, { headers: headers });
eventSource.onmessage = (event => {
observer.next(event);
this.zone.run(() => {
console.log('prpprpr');
});
});
eventSource.onopen = (event) => {
observer.next(event);
};
eventSource.onerror = (error) => {
if (eventSource.readyState === 0) {
console.log('The stream has been closed by the server.');
eventSource.close();
observer.complete();
} else {
observer.error('EventSource error: ' + error);
}
};
});
}
It only opens connection, does not receive events (Method onopen works once, onmessage - never). Server sends them though.
Any ideas how to fix this?
Turned out that if you set event name on server, you cannot receive it by onmessage method.
In the example the event name was set to "random". In order to receive it you have to do it like this:
eventSource.addEventListener('random', function (event) {
console.log(event);
});

Socket.io transport close and ping timeout error

Socket client is getting disconnected either due to transport close or pingtimeout error. And it happens randomly. Sometime the socket client is stable for couple of hours and after that is start disconnecting randomly.Can anyone help me finding the issue.
Socket-Client version : 2.1.0
Socket Server version : 2.1.0,
Client Code
const socket = require('socket.io-client')
let url = 'http://localhost:5050'
let clientSocket = socket.connect(url, {
reconnection: true,
forceNew: true,
secure: true
})
clientSocket.on("connect", function (data) {
// console.log(clientSocket)
console.log("connection established");
});
clientSocket.on("event", function(data) {
console.log(data)
})
Server Code
const socketio = require('socket.io');
this.io = socketio.listen(this.server,
{
'pingInterval': PING_INTERVAL,
'pingTimeout': PING_TIMEOUT
});
this.io.on('connection', function (socket) {
// const consumer = new ConsumerGroup(options, topic);
// reading data from add event and sending back the same data
console.log('Connected', socket.id);
const token = socket.handshake.query.token;
socket.on('disconnect', function () {
console.log(socket.id + ' -> Disconnected');
});
consumer.on('ready', function (message) {
console.log('Ready');
});
consumer.on('message', function (message) {
// sending message on socket when we recieve the message from kafka\
socket.emit('alarm', message);
});
consumer.on('error', function (err) {
console.log('error', err);
});
});

Why isn't the server sending or the client receiving data via socket.io in my express app?

My node app posts an object (consisting of data collected in a form on the client) to Salesforce via their API. On receiving a success or error message, I would like to send it to the client-side, then display it. Socket.io seemed like the tool for this in my simple node/express3 app, but beyond the simple demo I'm not able to get data to pass between my server and my client.
My relevant server side code:
var express = require('express');
var port = 5432;
var app = module.exports = express();
var server = require('http').createServer(app);
var nforce = require('nforce');
var org = nforce.createConnection({
clientId: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
redirectUri: 'http://localhost:5432/oauth/_callback'
});
var io = require('socket.io').listen(server);
// here I authenticate with Salesforce, this works fine
app.post('/salesforce', function(req, res){
var lead = nforce.createSObject('Lead');
// here I construct the lead object, which also works fine
org.insert(lead, oauth, function(err, res) {
if (err === null) {
console.log(res);
leadSuccessMessage(res);
}
else {
console.log(err);
var error = {
errorCode: err.errorCode,
statusCode: err.statusCode,
messageBody: err.messageBody
};
console.log(error);
leadErrorMessage(error);
}
});
}
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
io.sockets.on('connection', function (socket) {
socket.emit('sfRes', resp);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
io.sockets.on('connection', function (socket) {
console.log("socket is: " + socket);
socket.emit('sfRes', err);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
And my relevant client side scripts:
<script src="/socket.io/socket.io.js"></script>
<script>
current.page = document.URL;
console.log("current page is: " + current.page);
var socket = io.connect(current.page);
socket.on('sfRes', function (data) {
console.log("client received: " + data);
fst.showLeadStatus(data);
socket.emit('thanks', {message: "received server feedback"});
});
</script>
When I post the form containing valid data using a spicy little AJAX call:
postToSF: function(){
$('#submitLead').on('click', function(e){
e.preventDefault();
var formData = $('#lead_form').serialize();
$.ajax({
type: 'POST',
url: '/salesforce',
data: formData,
success: function(){
fst.log('success!');
},
error: function(xhr, ajaxOptions, thrownError){
console.error(xhr.status); // 0
console.error(thrownError);
}
});
});
}
All I get are tears, and these in the server-side console:
// the result of `console.log(res)`
{ id: '00Qa000001FZfhKEAT', success: true, errors: [] }
// and proof that `leadSuccessMessage()` got called
called success message from server
Instead of calling this function from a client-side object as it's supposed to:
showLeadStatus: function(response){
if (response.success) {
fst.log("showing lead status as: " + response);
$('#leadStatus').addClass('success').removeClass('error').fadeIn().delay(4000).fadeOut();
}
else {
fst.log("showing lead status as: " + response);
$('#leadStatus').text(response.messageBody).addClass('error').removeClass('success').fadeIn().delay('4000').fadeOut();
}
$('#startOver').click();
}
Which works fine if I call it in the console passing it the data the server is supposed to be socketing over:
// this works, gosh darn it
fst.showLeadStatus({ id: '00Qa000001FZfhKEAT', success: true, errors: [] });
The Salesforce post error case doesn't surface anything to the client either. And there are no errors in the client or server console to contend with.
I'm stumped. Please help!
I would do something like this -
var mysocket = null;
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
mysocket = socket;
socket.on('thanks', function (data) {
console.log(data);
});
});
app.post('/salesforce', function(req, res){
....
....
})
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
if(mysocket)
mysocket.emit('sfRes', resp);
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
if(mysocket)
mysocket.emit('sfRes', err);
}

Resources