我尝试编写一个聊天应用程序。我使用(在服务器端): php
laravel 5.4
和 pusher
和(在客户端)vue.js
和laravel-echo
。
我已经建了一个聊天群,什么是“公共(public)聊天室”。现在我正在开发私有(private)聊天室。
我的问题:监听用户所属房间的所有 channel 的最佳实践(在客户端)是什么。
我的目标:检查(就像在 Facebook Messenger 网页上一样)私有(private)和公共(public)房间的每个 channel 。
现在我在 chat-window
组件中有这个:
created() {
axios.get('/chatroom').then(response => {
this.chatRooms = response.data;
console.log('get /chatroom response: ' + response.data);
});
axios.get('/messages').then(response => {
this.messages = response.data;
console.log('get /messages response: ' + response.data);
});
Echo.join('chatroom')
.here((users) => {
this.usersInRoom = users;
})
.joining((user) => {
this.usersInRoom.push(user);
})
.leaving((user) => {
this.usersInRoom = this.usersInRoom.filter(u => u != user)
})
.listen('MessagePosted', (e) => {
this.messages.push({
message: e.message.message,
user: e.user
});
});
}
});
但这仅监听聊天室
channel 。客户端如何监听所有聊天室(this.chatRooms
)?
提前感谢您的回答!
最佳答案
所以我发现每个用户都必须有自己的 channel 。
然后我修改了我的 chat-window
组件:
<template lang="html">
<div class="panel panel-default">
<div class="panel-heading" style="height: 60px">
<chat-room-picker :chatrooms="chatRooms" :newmessage="newmessage" :defaultchatroomid="pickedchatroomid" class="pull-left" v-on:chatroompicked="chatroompick"></chat-room-picker>
<chat-room-creator class="pull-right"></chat-room-creator>
</div>
<chat-room :chatroomid="pickedchatroomid" :newmessage="newmessage"></chat-room>
</div>
</template>
<script>
export default {
data() {
return {
userId: loggedUserFS.id,
userName: loggedUserFS.name,
chatRooms: chatRoomsFS,
pickedchatroomid: defaultChatRoomIdFS,
newmessage: {},
}
},
methods: {
chatroompick(id) {
this.pickedchatroomid = id;
},
},
created() {
// this.getCookiesParams();
var tmp = this.chatRooms[0];
this.pickedchatroomid = tmp.id;
var channelName = 'chat-' + this.userId;
console.debug(channelName + ", channel init.");
window.Echo.join(channelName)
.listen('NewMessageEvent', (e) => {
console.debug("incoming message on " + channelName + ": " + JSON.stringify(e));
console.debug(e.message.chatRoom_id + "==" + this.pickedchatroomid);
console.debug(channelName +" : "+ e.message.chatRoom_id + "==" + this.pickedchatroomid);
// TODO: finish it
if(e.message.chatRoom_id == this.pickedchatroomid) { // if the reciced message comes from the pickedchatroom
console.debug("reciced message comes from the pickedchatroom!");
this.newmessage = e;
} else { // if the reciced message does not come from the pickedchatroom
this.newmessage = e;
}
});
}
}
</script>
<style lang="css">
</style>
我制作了一个聊天室选择器
,它是一个下拉菜单,您可以用它更改聊天室。还有一个chat-room
组件,用于显示当前聊天室的消息。两个组件中都有 vue-watch
-es 并且新消息发生更改,聊天室添加消息(如果该消息属于当前聊天室),否则不执行任何操作,如果消息属于其他房间,chat-room-picker
就会开始闪烁。
聊天室选择器
观看:
watch : {
newmessage : function (value) {
var message = value;
var picker = $(".chatRoomPicker");
//TODO: check that the message belongs to current chat room
picker.addClass("blink");
picker.on("click", function() {
picker.removeClass("blink");
});
}
}
聊天室组件的观看部分:
watch : {
chatroomid : function (value) { // if chat-room is changed
this.getChatRoomMessages();
},
newmessage : function(value) { // TODO: here or parent component check the room of the message
console.debug("newmessage received:" + JSON.stringify(value));
var msgTmp = value.message;
msgTmp.user = value.user;
this.messages.push(msgTmp);
}
},
服务器端(在 Controller 中):
broadcast(new NewMessageEvent($message, $user, $usersOfChatRoom));
我的 NewMessageEvent
的 broadcastOn
方法如下所示:
public function broadcastOn()
{
$channels = [];
foreach ($this->usersOfChatRoom as $addressee) {
if($addressee->id != $this->user->id) {
array_push($channels, new PresenceChannel('chat-' . $addressee->id));
}
}
Log::debug("broadcastOn channels: " . json_encode($channels));
return $channels;
//
}
我知道它还没有完成,但我评论了应该在哪里完成代码。
这可能不是最优雅的方式,但它确实有效。如果其他人有其他解决方案请分享!
关于javascript 使用 echo 监听多个套接字 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44028198/