I am getting an error when using the code from Chapter 17. The error is as follows:
Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
at WebSocket.socket.onmessage (app\scripts\src\ws-client.js:18)
It seems to be related to this line: let data = JSON.parse(e.data) in the registerMessageHandler function. According to the book, e.data is a json string and each time “you” receive it “you” convert it to a JavaScript object which is what JSON.parse(e.data) is supposed to be doing. However, in googling the error I’m getting, the responses indicate that this error occurs when using JSON.parse on something that is already a JavaScript object. so is the line with the JSON.parse call not necessary? I’m quite confused here.
Had a similar issue. Check your websockets-server.js file for the section below. I was sending an additional value in the “clientSocket.send(data);” line to show which client window the data was coming from. This causes a json parsing error since it wasn’t correct json. Once removed, no issue.
socket.on('message', function (data) {
console.log('message received: ' + data);
messages.push(data);
var clientCount = 0;
ws.clients.forEach(function(clientSocket){
clientSocket.send(data);
});
});
I fixed my version of this problem by decoding the socket message into UTF-8 before the JSON parse.
UTF8 = new TextDecoder('utf-8'); // Only need to create once
msg = JSON.parse(UTF8.decode(event.data));
A more general problem is that the book code did not work for messages received from wscat, nor from the dummy server side chatbot created in the previous chapter.
With digging and experimentation I found that a ws websocket is not quite the same as a client side WebSocket. I finally got all three types of message to work by setting the client side websocket to binary
socket = new WebSocket(serverURL);
socket.binaryType = 'arraybuffer';
and by writing a more complicated onmessage handler:
// This code is complicated because there are three possible
// types of message: JSON serialized messages, plain text from
// wscat, and plain text from server side where a ws socket
// is not quite the same as a client side WebSocket
let msg = null;
let txt = null;
try {
txt = UTF8.decode(event.data);
msg = JSON.parse(txt);
// If we got here, serialized object
} catch (e) {
if (typeof(event.data) === 'string') {
// Server side ws
msg = event.data;
} else if (txt) {
// utf-8 decode worked but not JSON
msg = txt;
} else {
throw e;
}
}
callback(msg);
Longer, but more robust and means you can test with wscat.