Closed pospile closed 2 years ago
Hmm, this looks definitely like a bug. When does it occur? When the application is launched or when a WS controller receive an event? If it is when it receives an event, could you share the client code that emits the event?
Its when controller receives en event but everything inside that method is normally executed I think
@EventName('msg')
ping(ctx: WebsocketContext) {
console.log("event msg");
//return new WebsocketErrorResponse();
}
Because as you can see, if response get commented it still crashes on the same error right after it report problem with non existing response and console log is executed normally
event msg
[1] Error: The controller method "ping" should return a WebsocketResponse or a WebsocketErrorResponse.
[1] at Object.getWebsocketResponse (/node_modules/@foal/socket.io/lib/routes/get-websocket-response.js:35:23)
[1] at processTicksAndRejections (node:internal/process/task_queues:94:5)
[1] at Socket.<anonymous> (/node_modules/@foal/socket.io/lib/socketio-controller.service.js:52:38)
[1]
[1]/node_modules/@foal/socket.io/lib/socketio-controller.service.js:54
[1] return cb({
[1] ^
[1] TypeError: cb is not a function
[1] at Socket.<anonymous> (/node_modules/@foal/socket.io/lib/socketio-controller.service.js:54:32)
[1] at processTicksAndRejections (node:internal/process/task_queues:94:5)
[1] Program node ./build/index.js exited with code 1
And I dont have any client code yet, just testing it out with with Postman socket.io integration for now. But I will go and try to test it with actual js client.
Ok so the socket.io client library makes no difference ie:
<!doctype html>
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('i am client', {data: 'foo!', id: data.id});
});
socket.on('time', function(data) {
addMessage(data.time);
});
socket.on('error', console.error.bind(console));
socket.on('message', console.log.bind(console));
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
</script>
</head>
<body>
<ul id='messages'></ul>
</body>
</html>
and server code is:
import {
EventName,
SocketIOController,
WebsocketContext
} from '@foal/socket.io';
export class WebsocketController extends SocketIOController {
@EventName('i am client')
ping(ctx: WebsocketContext, payload) {
console.log("event msg");
console.log(payload);
//return new WebsocketErrorResponse();
}
onConnection(ctx: WebsocketContext): void | Promise<void> {
ctx.socket.emit("welcome", {"message": "ahojda"});
return super.onConnection(ctx);
}
}
Welcome message goes through as expected, socket.emit also works fine and it all fails at client emitting "i am client" message.
Also there is index.ts as it might be relevant:
import 'source-map-support/register';
import * as admin from 'firebase-admin';
// std
import * as http from 'http';
// 3p
import {Config, createApp, displayServerURL, ServiceManager} from '@foal/core';
// App
import { AppController } from './app/app.controller';
import {WebsocketController} from "./app/services";
async function main() {
const serviceManager = new ServiceManager();
const app = await createApp(AppController, { serviceManager });
const httpServer = http.createServer(app);
const port = Config.get('port', 'number', 3001);
const serviceAccount = require("../firebase.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
await serviceManager.get(WebsocketController).attachHttpServer(httpServer);
httpServer.listen(port, () => displayServerURL(port));
}
main()
.catch(err => { console.error(err.stack); process.exit(1); });
socket.io in yarn.lock
"@foal/socket.io@npm:^2.8.0":
version: 2.8.0
resolution: "@foal/socket.io@npm:2.8.0"
dependencies:
"@foal/core": ^2.8.0
reflect-metadata: ~0.1.13
socket.io: ~4.4.1
checksum: da8ad244edea664e87e05bdc746b9ad2b2ce285a8e1ea6d5fd3d7c270a0f85c5e465a1e6df95dabfb8ee664a296fd9a5202cf42a2ed35b6c797664eb04acbc77
languageName: node
linkType: hard
It should be latest version as per npm.
Thank you for you investigation. 👍
I found the issue. Setting aside the error that is raised because no response is returned, the TypeError: cb is not a function
error comes from the fact that the client does not provide a callback in its emit
function:
// Does not work
socket.emit('i am client', {data: 'foo!', id: data.id});
// Works
socket.emit('i am client', {data: 'foo!', id: data.id}, (data) => {
console.log(data);
});
It appears that, when no callback is provided in the client, the server sdk does not also pass a function to the on
method.
I'll work on a fix.
@pospile which version of Node are you on?
@LoicPoullain tried multiple, currently node 16.
The issue has been fixed in version 2.8.1 which will be released this week-end. Thank you for reporting this problem @pospile 👍
Version of FoalTS: 2.8.0
I tried updating my backend but I am still failing at this error:
What can be my problem, did I missed some step in upgrading the project to 2.8?
Thanks