vue使用socket.io聊天室踩坑

此项目的原作者地址链接:https://github.com/Yaer23/vue-chatroom
然后我照着这个在本地写发现一直在出问题,现在记录一下出现的问题和解决方法,也是各种试才终于成功
先看项目目录:
这里写图片描述
1.安装socket.io,发现很顺利,接下来就是各种错误
列表内容
2.然后启动服务端js
这里写图片描述
什么?没有socket.io,检查了一下,原来是我没有在package.json中配置,开启服务的js也要在这里配置一下
这里写图片描述
以后再出这种问题可以去这里看看有没有引入。
3.最笨的解决办法,这个项目因为之前做的安装了很多不需要的,还有问题的包,我就直接把modules下的包全删了再重新安装,浪费了很长时间
这里写图片描述
4.然后终于成功启动了服务端js
这里写图片描述
5.最坑的来了,使用localhost一直打不开页面,就像这样
这里写图片描述
这里不知道是什么问题,最后换了一个写法用http://127.0.0.1:8081居然可以了
6.终于登陆进来发消息页面发现加载不了参数:
这里写图片描述
不停地报这个错,也花了我很久去找,我看了很多网站上对这个问题的解决办法都不一样,我开始以为我的js写错,后来发现不是js,应该先从引入socket.io这里入手,
开始使用<script src="https://cdn.bootcss.com/socket.io/2.1.0/socket.io.js"></script>
还是有问题又换成<script src="http://127.0.0.1:8081/socket.io/socket.io.js"></script>
报错
这里写图片描述
最后换成了<script src="http://localhost:8081/socket.io/socket.io.js"></script>才行。
还是要多试一下才行,在这些错误中也对socket.io的用法有了更深入的理解。
现在把几个页面展示一下:

  • index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>chatroom</title>
    <link rel="stylesheet" href="http://at.alicdn.com/t/font_637013_b0ubbuoti59daemi.css">
  </head>
  <body>
    <div id="app"></div>
    <script src="http://localhost:8081/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <!-- built files will be auto injected -->
  </body>

</html>
  • main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'


Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
  • app.vue
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
import login from './components/login.vue'
import chatRoom from './components/chatRoom.vue'
export default {
  name:'App',
  components:{
    login,
    chatRoom
  }
}
</script>

<style>
html,body {
  margin: 0;
  padding: 0;
}
</style>
  • index.js
import Vue from 'vue'
import Router from 'vue-router'
import chatRoom from '@/components/chatRoom'
import login from '@/components/login'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'login',
      component: login
    },
    {
      path: '/chatRoom',
      name: 'chatRoom',
      component: chatRoom
    }
  ]
})

组件:
- chatRoom.vue

<template>
    <div id="chatroom">
        <div class="header">
            <div class="roomUser">
                <p>ChatRoom({{clientNum}}users)</p>
            </div>
        </div>
        <div class="body">
            <div v-for="(item,index) in msgs" :key="index">
                <div v-if="item.msgType=='online'" class="onlineMsg">
                    <div class="sysTime">{{item.time}}</div>
                    <div class="online">{{item.username}}上线</div>
                </div>
                <div v-else-if="item.msgType=='offline'" class="offlineMsg">
                    <div class="sysTime">{{item.time}}</div>
                    <div class="online">{{item.username}}下线</div>
                </div>
                <div v-else-if="item.msgType=='clientMsg'" class="clientMsg">
                    <div class="sysTime">{{item.time}}</div>
                    <div v-if="item.username==$route.query.username" class="self">
                        <div class="bubble">
                            <div class="chatBubble">{{item.msg}}</div>
                            <div class="triangle"></div>
                        </div>
                        <div class="user">{{item.username}}</div>
                    </div>
                    <div v-else class="others">
                        <div class="user">{{item.username}}</div>
                        <div class="bubble">
                            <div class="chatBubble">{{item.msg}}</div>
                            <div class="triangle"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    <div class="footer">
      <div class="msgInput">
        <input v-model="msg" autofocus class="input" type="text" @keydown.enter="send(msg)" placeholder="press Enter to send message" >
      </div>
    </div>
    </div>
</template>

<script>
var moment = require("moment")
import storage from '../../server/storage';
export default {
    name:"chatRoom",
    data(){
        return{
            socket:null,
            msg:"",
            msgs:storage.fetch(),
            clientNum:0,
            showEmoji:false,
            emoji:[]          
        }
    },
    mounted:function(){
        this.socket = io("http://localhost:8081");
        if(this.$route.query.username){
            this.socket.emit('online',this.$route.query.username);
        }else{
            alert("Login First")
            this.$router.push("/");
        }
        this.socket.on('online',data=>{
            this.msgs.push({
                msgType:"online",
                username:data,
                time:moment().format("HH:mm:ss")
            })
            storage.save(this.msgs);
        })
        this.socket.on('broadcastMsg',data=>{
            this.msgs.push({
                msgType:"clientMsg",
                username:data.username,
                msg: data.msg,
                time:moment().format("HH:mm:ss")
            })
            storage.save(this.msgs);
        })
        this.socket.on('offline',data=>{
            this.msgs.push({
                msgType:"offline",
                username:data,
                time:moment().format("HH:mm:ss")
            })
            storage.save(this.msgs);
        })
        this.socket.on("clientNum",num=>{
            this.clientNum = num
        })
    },
    updated:function(){
        this.$nextTick(function(){
            var oBody = document.querySelector(".body");
            oBody.scrollTop = oBody.scrollHeight;
        })
    },
    methods:{
        send:function(data){
            var transdata = {
                msg:data,
                username:this.$route.query.username
            };
            if(data){
                this.socket.emit("msg",transdata);
                this.msg="";
            }else{
                alert('消息为空!');
            }
        }
    }
}
</script>

<style scoped>
a {
  text-decoration: none;
}
a:hover {
  color: brown;
}
.chatroom {
  width: 400px;
  height: 600px;
  position: relative;
  border: 1px solid #999;
  margin: 0 auto;
  margin-top: 15px;
}
.header {
  background-color: rgb(112, 114, 175);
  height: 50px;
  display: -webkit-flex;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.body {
  height: 505px;
  width: 100%;
  overflow: auto;
  text-align: center;
}
.iconfont {
  font-size: 24px;
}
.logout,
.about {
  padding: 7px;
}
.sysTime {
  color: #999;
  font-size: 13px;
  margin-bottom: 3px;
}
.onlineMsg,
.offlineMsg,
.clientMsg{
  margin-bottom: 10px;
  height: 50px;
  width: 100%;
}
.clientMsg{
  position: relative;
}
.online,
.offline {
  display: inline-block;
  height: 23px;
  padding-left: 10px;
  padding-right: 10px;
  border-radius: 3px;
  color: #999;
  text-align: center;
  line-height: 23px;
  background-color: rgb(209, 209, 209);
  font-size: 16px;
  box-sizing: border-box;
}
.self {
  position: absolute;
  right: 14px;
}
.others {
  position: absolute;
  left: 14px;
}
.bubble {
  display: inline-block;
  position: relative;
}
.chatBubble {
  height: 30px;
  line-height: 30px;
  background-color: rgb(198, 205, 243);
  font-size: 16px;
  color: rgb(58, 58, 58);
  border-radius: 10px;
  padding-left: 10px;
  padding-right: 10px;
}
.self .triangle {
  position: absolute;
  right: -10px;
  top: 10px;
  border-left: 10px solid rgb(198, 205, 243);
  border-bottom: 10px solid transparent;
}
.others .triangle {
  position: absolute;
  left: -10px;
  top: 10px;
  border-right: 10px solid rgb(198, 205, 243);
  border-bottom: 10px solid transparent;
}
.self .user {
  display: inline-block;
  margin-left: 10px;
}
.others .user {
  display: inline-block;
  margin-right: 10px;
}
.footer {
  height: 45px;
  width: 100%;
  position: absolute;
  bottom: 0;
  display: -webkit-flex;
  display: flex;
}
.emoji {
  position: absolute;
  left: 10px;
  top: 10px;
}
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
.emojiList {
display: inline;
  /* width: 400px;
  height: 145px; */
  position: absolute;
  bottom: 30px;
  border: 1px solid #ccc;
  background-color: rgb(244, 248, 250);
  box-sizing: border-box;
  padding: 0px;
}
.emojiList li {
  display: inline-block;
  margin: 0;
  cursor: pointer;
  width: 24px;
  height: 24px;
  box-sizing: border-box;
}
.emojiList li:hover {
  border: 1px solid #ccc;
}
.msgInput {
  position: relative;
  width: 100%;
  height: 45px;
}
.msgInput .input {
  box-sizing: border-box;
  width: 350px;
  height: 45px;
  border: 1px solid #eee;
  padding-left: 50px;
  background-color: #d1b8b8;
  font-size: 18px;
  caret-color: rgb(62, 141, 231);
  color: rgb(55, 125, 182);
}
</style>
  • login.vue
<template>
    <div id="container">
        <input type="text" v-model="username" @keydown.enter="login" autofocus>
    </div>
</template>

<script>
export default {
    name:"Login",
    data () {
        return {
            username:""
        }
    },
    methods:{
        login(){
            if(this.username){
                this.$router.push({path: '/chatroom', query:{username:this.username}});
            }else{
                alert("请输入您的名字")
            }
        }
    }
}
</script>

<style>

</style>

js
- app.js

var app = require('http').createServer(),
    io = require('socket.io')(app);
app.listen(8081);
PORT=8081,
clientCount=0;
io.on('connection',function(socket){
    socket.on('online',function(data){
        clientCount++;
        io.emit('clientNum',clientCount);
        socket.username = data
        io.emit('online',data)
        console.log('user:'+socket.username+'connected!')
    })
    socket.on('msg',function(data){
        io.emit('broadcastMsg',data);
        console.log(JSON.stringify(data)+"发消息了")
    })

    socket.on('disconnect',function(){
        clientCount--;
        io.emit('clientNum',clientCount);
        socket.broadcast.emit('offline',socket.username);
        console.log(socket.username+'下线了~')
    })
})

console.log('listening at :' +PORT)
// 
  • storage.js
const STORAGE_KEY = 'chatlist';
export default{
  fetch:function(){
      return JSON.parse(window.sessionStorage.getItem(STORAGE_KEY)||'[]');
  },
  save:function(item){
      window.sessionStorage.setItem(STORAGE_KEY,JSON.stringify(item));
  }
}

最后放一个成功的图
这里写图片描述
肯定还有很多需要改进的地方。一点点小成果
我的项目地址:https://github.com/Jasonshanshu/myfirstchatroom#chatroom

猜你喜欢

转载自blog.csdn.net/Jason_ss/article/details/81169582