使用ws通过websocket发送对象:无法反序列化

Posted

技术标签:

【中文标题】使用ws通过websocket发送对象:无法反序列化【英文标题】:Sending objects through websocket using ws: Can't deserialize 【发布时间】:2018-08-01 05:46:59 【问题描述】:

所以我尝试通过我的 websocket 发送一个对象,将其转换为 json,然后在它返回时返回。不幸的是,它给了我以下错误。 console.log 显示它是有效的 JSON,但不知何故,它在服务文档中的 JSON.parse 处给了我一个错误。谁能看到我做错了什么?

错误

core.js?223c:1440 ERROR SyntaxError: Unexpected token c in JSON at position 0
    at JSON.parse (<anonymous>)
    at WebSocket._this.ws.onmessage [as __zone_symbol__ON_PROPERTYmessage] (movie-chat.service.ts?6086:22)
    at WebSocket.wrapFn (zone.js?fad3:1166)

event.data 的console.log 结果(有效的json)

"message":"good boy","extra":"extra"

movie-chat.service.ts

import Injectable from "@angular/core";
import 'rxjs/rx';
import HttpClient from "@angular/common/http";
import Observable from "rxjs/Observable";

// We need @injectable if we want to use http
@Injectable()

export class MovieChatService 
ws;

constructor(private http: HttpClient) 


// receive events
createObservableSocket(url:string)
    this.ws = new WebSocket(url);
    return new Observable(observer => 
        this.ws.onmessage = (e) => 
            console.log(e.data);
            var object = JSON.parse(e.data);
            observer.next(object);
        
        this.ws.onerror = (event) => observer.error(event);
        this.ws.onclose = (event) => observer.complete();
    
    );

// send events
sendMessage(message)  
    message = JSON.stringify(message);
    console.log(message);
    this.ws.send(message); 



消息的后端处理

var wss = new Websocket.Server(port:3185);
var CLIENTS = [];

wss.on('connection',
    function(websocket) 

        CLIENTS.push(websocket);
        websocket.send('connected to socket');


        websocket.on('message', function (message) 
            console.log('Server received:', message);
            sendAll(message)
        );

        websocket.on('close', function(client) 
            CLIENTS.splice(CLIENTS.indexOf(client), 1);
        );

        websocket.on('error', function(client) 
            CLIENTS.splice(CLIENTS.indexOf(client), 1);
        );
);

movie-chat.component.ts

import Component, OnInit from "@angular/core";
import  MovieChatService from "./movie-chat.service";

@Component(
    selector: 'app-movie-chat',
    templateUrl: './movie-chat.component.html',
    styleUrls: ['./movie-chat.component.css']
)

export class MovieChatComponent implements OnInit

    fullName;
    messageFromServer;
    title = 'Websocket Demo';
    url;
    ws;
    messages = [];

    constructor(private movieChatService: MovieChatService)
    

    ngOnInit()
        this.fullName = localStorage.getItem('fullName');
        this.url = 'ws://localhost:3185';
        this.movieChatService.createObservableSocket(this.url)
            .subscribe(data => 
                    this.messageFromServer = data;
                ,
                err => console.log(err),
                () => console.log('The observable stream, is complete'));
    

    sendMessageToServer()
        console.log('Client sending message to websocket server');
        this.movieChatService.sendMessage(
            message: 'good boy',
            extra: 'extra'
        );
    

【问题讨论】:

【参考方案1】:

您似乎正在尝试解析 Json 对象,

"message":"good boy","extra":"extra"

JSON.parse 期望字符串参数,并且您正在传递一个 Json 对象,以便引发异常。 我们尝试用 try and catch 包围 Parse

import Injectable from "@angular/core";
import 'rxjs/rx';
import HttpClient from "@angular/common/http";
import Observable from "rxjs/Observable";

// We need @injectable if we want to use http
@Injectable()

export class MovieChatService 
ws;

constructor(private http: HttpClient) 


// receive events
createObservableSocket(url:string)
    this.ws = new WebSocket(url);
    return new Observable(observer => 
        this.ws.onmessage = (e) => 
            console.log(e.data);
            try 
                var object = JSON.parse(e.data);
                observer.next(object);
             catch (e) 
                 console.log("Cannot parse data : " + e);
            
        
        this.ws.onerror = (event) => observer.error(event);
        this.ws.onclose = (event) => observer.complete();
    
    );

// send events
sendMessage(message)  
    message = JSON.stringify(message);
    console.log(message);
    this.ws.send(message); 



【讨论】:

有办法解决这个问题吗? 尝试向服务器发送消息时出现错误? 当我从服务器取回上述内容时,我在服务中收到了上述内容。当我尝试将此 JSON 转换回 javascript 对象时发生错误。 我编辑了我的帖子,尝试更新 on message 方法并重新启动服务器,如果问题仍然存在,请告诉我。 您能否像我编辑帖子一样使用 try and catch 语句来确定引发异常的数据内容。【参考方案2】:

所以,我实际上并没有按照我想要的方式解决它,但我发现可以通过 websocket 发送数组。我这样做了,在接收端我将它转移到服务文件中的一个对象中。它现在完成了这项工作。如果有人知道更好的解决方案,请告诉我:)

createObservableSocket(url:string)
        this.ws = new WebSocket(url);
        return new Observable(observer => 
            this.ws.onmessage = (e) => 
                var obj = e.data.split(',');
                console.log(obj);
                obj = 
                    name: obj[0],
                    msg: obj[1]
                ;
                console.log(obj);
                observer.next(obj);
            
            this.ws.onerror = (event) => observer.error(event);
            this.ws.onclose = (event) => observer.complete();
        
        );
    

【讨论】:

以上是关于使用ws通过websocket发送对象:无法反序列化的主要内容,如果未能解决你的问题,请参考以下文章

无法在 REST WS 中反序列化 LocalDate 值

c# sorket序列化反序列化如何如何传接Object?

未捕获的 InvalidStateError:无法在“WebSocket”上执行“发送”:

如何在 Haskell 中序列化/反序列化通过网络发送的对象?

IPC反序列化异常仅在接收数据时?发送工作正常

GWT JPA - 无法反序列化响应