简体   繁体   中英

How it should be done properly to send and receive message with user ID using websockets in Django and Angular?

I am going to create chatbot using websockets. Each user can have their own account. I have Django backend and frontend written in Angular. At the moment I have a problem with message object. To wit I get this in backend:

django_1  | django.db.utils.IntegrityError: null value in column "user_id" violates not-null constraint
django_1  | DETAIL:  Failing row contains (212, {"message":"Hello"}, null).

It looks as I wouldn't send user ID from frontend. Maybe I should send something like this {"message":"Hello", "id":1} ? I wonder how can I solve it and how it should be done properly?

My Django message model looks in this way:

class Message(models.Model):
    user = models.ForeignKey('auth.User')
    message = models.CharField(max_length=200)

This is my backend consumer:

@channel_session_user_from_http
def msg_consumer(message):
    text = message.content.get('text')
    Message.objects.create(
        message=text,
    )
    Group("chat").send({'text': text})

@channel_session_user
def ws_connect(message):
    # Accept the connection
    message.reply_channel.send({"accept": True})
    # Add to the chat group
    Group("chat").add(message.reply_channel)

    message.reply_channel.send({
        "text": json.dumps({
            'message': 'Welcome'
        })
    })

@channel_session_user
def ws_receive(message):

    message.reply_channel.send({"accept": True})
    print("Backend received message: " + message.content['text'])
    Message.objects.create(
        message = message.content['text'],
    )

    Channel("chat").send({
        "text": json.dumps({
             'message': 'Can we start?'
         })
    })

@channel_session_user
def ws_disconnect(message):
    Group("chat").discard(message.reply_channel)

This is part of my Angular component:

export class HomeComponent {

    response: string;
    response2: string;

    constructor(
        private chatService: ChatService,
        private router: Router,
        private http: Http,
    ) {

        chatService.messages.subscribe(msg => {
            this.response = msg.message;
      console.log("Response from backend: " + msg.message);
        });

    }
    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);
        return this.message.message;
    }

  send(msg) {
     this.message.message = msg;
     this.sendMsg();
  }

      login() {
        return this.http.get('/data', )
            .map(response => response.json())
            .subscribe(response2 => this.response2 = response2);
    }


}

@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>();
}

UPDATE At the moment I solved it in the way shown below in backend.

def ws_receive(message):

message.reply_channel.send({"accept": True})
print("Backend received message: " + message.content['text'])
data = json.loads(message.content['text'])

Message.objects.create(
    user_id=data['user_id'],
    message = data['message'],
)

Error seems to indicate your Message instance was created without user_id . What if you add this argument when creating a new Message instance ?

@channel_session_user_from_http
def msg_consumer(message):
    text = message.content.get('text')
    Message.objects.create(
        user=message.user,  # <- Here is the user associated
        message=text,
    )
    Group("chat").send({'text': text})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM