Netty实现websocket聊天程序-前端页面

6 篇文章 0 订阅
2 篇文章 0 订阅

效果图

在这里插入图片描述

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
import vuescroll from "vuescroll"
import "vuescroll/dist/vuescroll.css"
Vue.config.productionTip = false
Vue.use(Antd)
Vue.use(vuescroll)//使用
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

package.json

{
  "name": "cms-pc",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  "main": "background.js",
  "dependencies": {
    "ant-design-vue": "^1.7.8",
    "axios": "^0.24.0",
    "core-js": "^3.8.3",
    "vue": "^2.6.14",
    "vue-router": "^3.5.1",
    "vuex": "^3.6.2",
    "electron": "^17.1.2",
    "vuescroll": "^4.17.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-vuex": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "vue-template-compiler": "^2.6.14",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "vue-cli-plugin-electron-builder": "^1.3.5"
  }
}

vue组件

<template>
    <div class="index">
        <a-row :gutter="[10,10]">
            <a-col :span="24">
                <h2 v-text="'You are talking to: '+message2UserId"/>
                <div class="messagesWrapper">
                    <vue-scroll ref="chatMessagesScroller" :ops="ops" style="width:100%;">
                        <div class="chatMessages">
                            <a-row :gutter="[10,10]">
                                <a-col v-for="(message,index) in chatMessages" :key="index" :span="24">
                                    <div :class="['chatMessageItem',message.fromId === loginUserId ? 'send' : 'receive']">
                                        <div class="messageAuthor">
                                            <a-avatar :size="45" icon="user"/>
                                        </div>
                                        <div class="messageInfo">
                                            <div class="messageTime">2022-03-28</div>
                                            <div :class="['chat-bubble',message.fromId === loginUserId ?
                                                'chat-bubble-right chat-bubble-success':'chat-bubble-left chat-bubble-primary']"
                                                 :id="'chatMessage_'+index">
                                                <span v-text="message.messageInfo"/>
                                            </div>
                                        </div>
                                    </div>
                                </a-col>
                            </a-row>
                        </div>
                    </vue-scroll>
                </div>
                <a-textarea v-model="messageInfo" placeholder="input message" rows="4"/>
                <a-button type="primary" v-on:click="sendMessage" icon="enter" style="float: right;margin-top:10px">send</a-button>
            </a-col>
            <a-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
                <span>
                    当前状态:<span :style="isLogined ? 'color:green;':'color: red;'" v-text="isLogined ? '已登录': '未登录'"/>
                </span>
                <a-input-search v-model="loginUserId" placeholder="your id" @search="imLogin">
                    <a-button type="primary" slot="enterButton">
                        login
                    </a-button>
                </a-input-search>
            </a-col>
            <a-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
                <label>chat to user:</label>
                <a-input v-model="message2UserId" placeholder="chat target user id" style="width:100%"/>
            </a-col>
        </a-row>
    </div>
</template>

<script>
    export default {
        name: "index",
        data() {
            return {
                loginUserId: '',
                socket: undefined,
                message2UserId: '',
                messageInfo: '',
                chatMessages: [],
                isLogined: false,
                ops: {
                    vuescroll: {},
                    scrollPanel: {
                        scrollingX: false
                    },
                    rail: {
                        keepShow: true
                    },
                    bar: {
                        hoverStyle: true,
                        onlyShowBarOnScroll: false, //是否只有滚动的时候才显示滚动条
                        background: "#929292",//滚动条颜色
                        opacity: 0.5,//滚动条透明度
                        'overflow-x': "hidden"
                    }
                },
                isSending: false,
            }
        },
        methods: {
            initSocketConnect() {
                let that = this;
                if (window.WebSocket || window.MozWebSocket) {
                    that.socket = new WebSocket("ws://localhost:7777/ws");
                    that.socket.onmessage = function (event) {
                        let messagePacket = JSON.parse(event.data);
                        let msgCommand = messagePacket.command;
                        if (msgCommand !== 'HEARTBEAT_RESPONSE') {
                            that.processMessage(messagePacket);
                        }
                    };

                    that.socket.onopen = function (event) {
                        console.log("websocket connected");
                        that.startHeartBeat();
                    };

                    that.socket.onclose = function (event) {
                        console.log("websocket disConnected");
                    };
                } else {
                    console.log("your browser does not support websocket");
                }
            },
            startHeartBeat() {
                let that = this;
                setInterval(function () {
                    let packet = {};
                    packet.command = "3";
                    that.socket.send(JSON.stringify(packet));
                }, 5000);
            },
            imLogin() {
                let that = this;
                if (that.loginUserId) {
                    let loginPacket = {};
                    loginPacket.dataInfo = {
                        userId: that.loginUserId,
                        password: "123456",
                        clientType: "web",
                        clientVersion: "1",
                    };
                    loginPacket.command = "1";
                    that.socket.send(JSON.stringify(loginPacket));
                    that.isLogined = true;
                } else {
                    that.$notification['info']({
                        message: 'please input your loginId',
                    });
                }
            },
            processMessage(messagePacket) {
                let that = this;
                let msgCommand = messagePacket.command;
                switch (msgCommand) {
                    case "SYS_NOTIFY_REQUEST":
                        that.processSysNotifyPacket(messagePacket);
                        break;
                    case "P2P_MESSAGE_REQUEST":
                        that.processP2pMessagePacket(messagePacket);
                        break;
                    default:
                        console.log("msg type to do...");
                }

            },
            processSysNotifyPacket(notifyPacket) {
                let that = this;
                let notifyType = notifyPacket.notifyType;
                switch (notifyType) {
                    case "CLIENT_ONLINE":
                        that.processUserOnline(notifyPacket.jsonNotifyInfo);
                        break;
                    case "CLIENT_OFFLINE":
                        that.processUserOffline(notifyPacket.jsonNotifyInfo);
                        break;
                    default:
                        console.log("process sys notify...");
                }
            },
            processUserOnline(onlineInfo) {
                let that = this;
                let userObj = JSON.parse(onlineInfo);
                let onlineUser = userObj.onlineUser;
                if (that.loginUserId !== onlineUser) {
                    if (window.Notification) {
                        Notification.requestPermission(function (status) {
                            var n = new Notification('上线通知', {body: '用户:' + userObj.onlineUser + "上线了!"});
                        });
                    }
                }
            },
            processUserOffline(offlineInfo) {
                let that = this;
                let userObj = JSON.parse(offlineInfo);
                let userId = userObj.offlineUser;
                if (that.loginUserId !== onlineUser) {
                    if (window.Notification) {
                        Notification.requestPermission(function (status) {
                            var n = new Notification('下线通知', {body: '用户:' + userId + "下线了!"});
                        });
                    }
                }
            },
            sendMessage() {
                let that = this;
                if (!window.WebSocket && !window.MozWebSocket) {
                    alert("your browser does not support websocket");
                    return;
                }
                if (that.socket.readyState === WebSocket.OPEN) {
                    if (that.message2UserId) {
                        if (that.isLogined) {
                            if (that.messageInfo) {
                                if (that.message2UserId !== that.loginUserId) {
                                    that.isSending = true;
                                    let p2pMessagePacket = {};
                                    p2pMessagePacket.dataInfo = {
                                        fromId: that.loginUserId,
                                        toId: that.message2UserId,
                                        messageInfo: that.messageInfo,
                                    };
                                    p2pMessagePacket.command = "5";
                                    that.chatMessages.push(p2pMessagePacket.dataInfo);
                                    that.socket.send(JSON.stringify(p2pMessagePacket));
                                    that.messageInfo = '';
                                    that.scrollMessages2Bottom();
                                    that.isSending = false;
                                } else {
                                    that.$notification['info']({
                                        message: 'you can not chat with yourself',
                                    });
                                }
                            } else {
                                that.$notification['info']({
                                    message: 'chat message can not be empty!',
                                });
                            }
                        } else {
                            that.$notification['info']({
                                message: 'please login before chat to someone!',
                            });
                        }
                    } else {
                        that.$notification['info']({
                            message: 'please input userId which you wanna to chat',
                        });
                    }
                } else {
                    console.log("WebSocket connect failed");
                }
            },
            processP2pMessagePacket(messagePacket) {
                let that = this;
                that.chatMessages.push(messagePacket);
                that.scrollMessages2Bottom();
            },
            scrollMessages2Bottom() {
                let that = this;
                let targetEleId = "#chatMessage_" + (that.chatMessages.length - 1);
                console.log("targetEle:" + targetEleId);
                setTimeout(function () {
                    that.$refs.chatMessagesScroller.scrollIntoView(targetEleId, 100);
                }, 100);
            }
        },
        mounted() {
            let that = this;
            that.initSocketConnect();
        }
    }
</script>

<style scoped>
    .index {
        width: 60%;
        margin: 0 auto;
        height: 100%;
        margin-top: 60px;
    }

    .messagesWrapper {
        height: 60vh;
        background-color: rgba(255,255,255,.6);
        border-radius: 4px;
        margin-bottom: 20px;
    }
    .chatMessages{
        padding: 20px;
    }
    .chatMessageItem{
        width: 100%;
        display: flex;
        align-items: flex-start;
    }
    .chatMessageItem .messageInfo{
        width: 0;
        flex: 1;
    }
    .chatMessageItem.send{
        flex-direction: row-reverse;
        justify-content: flex-end;
    }
    .chatMessageItem.send .messageAuthor{
        margin-left: 10px;
    }
    .chatMessageItem.send .messageInfo{
        text-align: right;
    }
    .chatMessageItem.receive{
        flex-direction: row;
        justify-content: flex-start;
    }

    .chatMessageItem.receive .messageAuthor{
        margin-right: 10px;
    }
    .chatMessageItem.receive .messageInfo{
        text-align: left;
    }
    .chat-bubble {
        color: #333;
        box-shadow: 3px 5px 15px rgba(0, 0, 0, .2);
        padding: 5px 10px;
        width: auto;
        max-width: 50%;
        text-align: left;
        display: inline-block !important;
        position: relative;
        word-break: break-all;
        background-color: #ffffff;
        transition: all .2s;
        cursor: pointer;
        margin-bottom: 10px;
    }

    .chat-bubble:hover {
        transform: scale(1.03);
    }

    .chat-bubble-left {
        float: left;
        border-radius: 0 5px 5px 5px;
    }

    .chat-bubble-left:before {
        content: '';
        width: 6px;
        height: 6px;
        left: -6px;
        top: 0;
        position: absolute;
        border-left: 3px solid transparent;
        border-bottom: 3px solid transparent;
        border-top: 3px solid #ffffff;
        border-right: 3px solid #ffffff;
    }

    .chat-bubble-right {
        float: right;
        border-radius: 5px 0 5px 5px;
    }

    .chat-bubble-right:after {
        content: '';
        width: 6px;
        height: 6px;
        right: -6px;
        top: 0;
        position: absolute;
        border-left: 3px solid #ffffff;
        border-bottom: 3px solid transparent;
        border-top: 3px solid #ffffff;
        border-right: 3px solid transparent;
    }

    /**
       chat-bubble-primary
     */
    .chat-bubble-left.chat-bubble-primary {
        background: linear-gradient(90deg, #2b92e4, #30a1dc) !important;
        color: #ffffff !important;
    }

    .chat-bubble-left.chat-bubble-primary:before {
        border-right: 3px solid #2b92e4 !important;
        border-top: 3px solid #2b92e4 !important;
    }

    .chat-bubble-right.chat-bubble-primary {
        background: linear-gradient(90deg, #30a1dc, #2b92e4) !important;
        color: #ffffff !important;
    }

    .chat-bubble-right.chat-bubble-primary:after {
        border-left: 3px solid #2b92e4 !important;
        border-top: 3px solid #2b92e4 !important;
    }

    /**
       chat-bubble-success
     */
    .chat-bubble-left.chat-bubble-success {
        background: linear-gradient(90deg, #4caf50, #66b869) !important;
        color: #ffffff !important;
    }

    .chat-bubble-left.chat-bubble-success:before {
        border-right: 3px solid #4caf50 !important;
        border-top: 3px solid #4caf50 !important;
    }

    .chat-bubble-right.chat-bubble-success {
        background: linear-gradient(90deg, #66b869, #4caf50) !important;
        color: #ffffff !important;
    }

    .chat-bubble-right.chat-bubble-success:after {
        border-left: 3px solid #4caf50 !important;
        border-top: 3px solid #4caf50 !important;
    }
</style>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值