I try to do a client-server application with on the client side a Angular2/typescript web site and on the server side a Kitura server in Swift on Mac OSX. On the client side, the typescript code instanciates an EventSource object :
this.eventSource = new EventSource(this.webSocketServerUrl);
this.eventSource.onopen = (event: Event): any => {
console.log("ServerNotificationsService.onopen - " + JSON.stringify(event) + " " + this.eventSource.readyState);
event.stopPropagation();
return null;
}
this.eventSource.onerror = (event: sse.IOnMessageEvent) => {
console.log("ServerNotificationsService.onerror - " + JSON.stringify(event) + " " + this.eventSource.readyState);
}
this.eventSource.onmessage = (event: Event): any => {
console.log("ServerNotificationsService.onmessage - " + JSON.stringify(event) + " " + this.eventSource.readyState);
event.stopPropagation();
return null;
}
console.log("ServerNotificationsService.constructor - " + this.eventSource.readyState);
On the server side, my code to handle the GET request looks like this :
router.get("/notifications") { request, response, next in
response.headers.append("Access-Control-Allow-Origin", value: "*")
if((request.accepts(header: "Accept", type: "text/event-stream")) != nil)
{
response.headers.append("content-type", value: "text/event-stream; charset=utf-8")
response.headers.append("cache-control", value: "no-cache")
response.headers.append("connection", value: "keep-alive")
try response.end()
Logger.sharedInstance.verbose(msg: "Request GET /notifications OK")
}
else
{
try response.status(.internalServerError).end()
Logger.sharedInstance.verbose(msg: "Request GET /notifications internalServerError")
}
next()
}
and to handle the post request :
router.post("/notifications") { request, response, next in
Logger.sharedInstance.verbose(msg: "Request POST /notifications ...")
response.headers.append("Access-Control-Allow-Origin", value: "*")
response.headers.append("content-type", value: "text/event-stream; charset=utf-8")
response.headers.append("cache-control", value: "no-cache")
response.headers.append("connection", value: "keep-alive")
while (true)
{
// wait here 5s. for the <nextMessage>
response.send(<nextMessage>)
try response.end()
Logger.sharedInstance.verbose(msg: "Request POST /notifications OK")
next()
}
}
The problem is that on the client side I receive the onopen notification, the event source's readyState pass to "Open" (1) but I receive immediately after a onerror notification and the readyState pass to "Connecting" (0). And so on : connecting, close, connecting, close, ... And in consequence the post request is never executed.
I will appreciate some help to have a code that maintains an open connexion.
Thank you,
Notux
Kitura does not currently support persistent, open HTTP connections. However, you might be able to replicate the functionality using WebSocket instead of server-sent events over HTTP (you will need to rewrite your frontend code to use WebSockets instead of EventSource): https://github.com/IBM-Swift/Kitura-WebSocket
And example Kitura-WebSocket app can be found here: https://github.com/IBM-Swift/Kitura-Chat-Server