[英]How can I send my message using websockets to backend
I am trying to create real-time chat between Django backend and Angular 4 frontend using PostgreSQL database. 我正在尝试使用PostgreSQL数据库在Django后端和Angular 4前端之间创建实时聊天。 Let's assume that I would like to create chatbot for instance like ALICE . 假设我要创建聊天机器人,例如ALICE 。 I am not sure but it seems to me that the most optimal solution would be to use websockets? 我不确定,但是在我看来,最佳的解决方案是使用websockets? I would like to write message on frontend, press enter and send my message to backend. 我想在前端写消息,按Enter键,然后将我的消息发送到后端。 Then I would like to get a response. 然后,我想得到回应。 I am trying to do this in the way shown below, however I get error. 我正在尝试以下面显示的方式执行此操作,但是出现错误。 I would like to input my own text on frontend, press enter and send it. 我想在前端输入我自己的文本,然后按Enter键并发送。
app.component.html: app.component.html:
<button (click)="sendMsg()">Send Message</button>
<h4>Type away! Press [enter] when done.</h4>
<div><key-up3 (keyup7)="send($event)"></key-up3></div>
app.component.ts: app.component.ts:
import { Component } from '@angular/core';
import { WebsocketService } from './websocket.service';
import { ChatService } from './chat.service';
import { Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ WebsocketService, ChatService ]
})
export class AppComponent {
constructor(private chatService: ChatService) {
chatService.messages.subscribe(msg => {
console.log("Response from websocket: " + msg);
});
}
private message = {
message: 'this is a test message'
}
sendMsg() {
console.log('new message from client to websocket: ', this.message);
this.chatService.messages.next(this.message);
this.message.message = '';
}
send(msg) {
this.message = msg;
this.sendMsg();
}
}
@Component({
selector: 'key-up3',
template: `
<input #box (keyup.enter)="keyup7.emit(box.value)">
<p>{{value}}</p>
`
})
export class KeyUpComponent_v3 {
@Output() keyup7 = new EventEmitter<string>();
}
websocket.service.ts: websocket.service.ts:
import { Injectable } from '@angular/core';
import * as Rx from 'rxjs/Rx';
@Injectable()
export class WebsocketService {
constructor() { }
private subject: Rx.Subject<MessageEvent>;
public connect(url): Rx.Subject<MessageEvent> {
if (!this.subject) {
this.subject = this.create(url);
console.log("Successfully connected: " + url);
}
return this.subject;
}
private create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);
let observable = Rx.Observable.create(
(obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
})
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
}
}
return Rx.Subject.create(observer, observable);
}
}
chat.service.ts: chat.service.ts:
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';
import { WebsocketService } from './websocket.service';
const CHAT_URL = 'ws://localhost:8000/';
export interface Message {
message: string
}
@Injectable()
export class ChatService {
public messages: Subject<Message>;
constructor(wsService: WebsocketService) {
this.messages = <Subject<Message>>wsService
.connect(CHAT_URL)
.map((response: MessageEvent): Message => {
let data = JSON.parse(response.data);
return {
message: data.message
}
});
}
}
UPDATE KeyUp.emit(box.value) in the template had upercase K. in the component was lowercase. 模板中的UPDATE KeyUp.emit(box.value)具有大写的K。组件中的小写。 However at this moment when I write something and press enter nothing happens. 但是,此时此刻,当我写东西并按Enter键时,什么也没发生。 Any suggestions? 有什么建议么?
You could add an EventEmitter to your keyUp component 您可以将EventEmitter添加到keyUp组件中
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'key-up3',
template: `
<input #box (keyup.enter)="keyUp.emit(box.value)">
<p>{{value}}</p>
`
})
export class KeyUpComponent_v3 {
@Output() keyUp = new EventEmitter<string>();
}
then in your main component listen for that event and set the message value accordingly.You will want to make your message
property public so it can be set the template. 然后在您的主组件中侦听该事件并相应地设置消息值。您将要使您的message
属性公开,以便可以将其设置为模板。
<h4>Type away! Press [enter] when done.</h4>
<div><key-up3 (keyUp)="message = $event"></key-up3></div>
Additionally: 另外:
RxJS has a class called the WebSocketSubject, you can use that to send and receive messages from your server very easily, here is a quick example of a service. RxJS有一个名为WebSocketSubject的类,您可以使用该类非常轻松地从服务器发送和接收消息,这是服务的快速示例。
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class SocketServer {
private webSocket$ = Observable.webSocket('ws://localhost:3000/');
public asObservable(): Observable<any> {
return this.webSocket$.retry();
}
public sendData(value) {
this.webSocket$.next(value);
}
}
.retry()
will attempt to reconnect to the WebSocket if it becomes disconnected .retry()
将在断开连接后尝试重新连接到WebSocket
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.