vue + socket.io实现一个简易聊天室示例代码
vue + vuex + elementui + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度。因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了。功能虽然不多,但还是有收获。设计和实现思路较为拙劣,恳请各位道友指正。
可以达到的需求
- 能查看在线用户列表
- 能发送和接受消息
使用到的框架和库
- socket.io做为实时通讯基础
- vuex/vue:客户端ui层使用
- element-ui:客户端ui组件
类文件关系图
服务端:
客户端:
服务端实现
实现聊天服务器的相关功能,包含通讯管道的创建、用户加入、消息的接受与转发等。
一、通讯服务建立
build/server-config.js:聊天服务器的入口
let socketio = require('socket.io'); let express = require('express'); let cxt = require('../src/services-server'); let httpport = 9001; let channelid = 1 let app = express(); app.get('/',function(req,res){ res.send('启动成功:' + httpport); }); let server = require('http').createserver(app); let io = socketio(server); io.on('connection',function(socket){ console.log('有客户端连接'); cxt.createchannel(channelid++,socket) }); server.listen(httpport); //用server连接 console.log('io listen success !! ' + httpport);
- 通过express创建一个server对象,然后利用socketio创建io对象
- 然后通过io的on方法监听connection事件
- 当有客户端连接时,触发connection事件,县立即调用"服务端上下文(后面简称cxt)"的createchannel方法创建一个管道,此时的管道上是没有用户信息的。
二、创建上下文(服务端上下文)
实现一个聊天室上下文,包含:用户、房间、消息、管道等数组,所以代码都在service-server目录中。
- index.js:聊天室服务端上下文创建入口,创建context,并初始化房间到上下文中。
- context.js:聊天室服务端上下文类,用户、房间、消息、管道等类在此中做集中管理。
- room目录:包含房间和房间集合的实现
- channel:服务端与客户端通讯的管道类
结合"通讯服务建立"中的connectiong事件的触,其后转到cxt.createchannel方法
createchannel (id, socket) { let channel = new channel(id, socket, this) channel.init() channel.index = this.channels.length this.channels.push(channel) }
此时会创建一个管道实例,然后初始化管道实例,并将管道添加到管道数组中。以下是初始化管道实例的代码:
init () { let self = this let roominfo = this.cxt.room.collections[0] this.roominfo = roominfo this.socket.join('roomid' + roominfo.id) this.socket.emit(this.cxt.eventkeys.emit.sendrooms, roominfo) /* send出去一个默认的房间 */ this.socket.on(this.cxt.eventkeys.client.registeruser, function (id, name) { console.log(id + '-' + name + '--' + self.id) self.cxt.createuserbyid(id, name, self.id) }) /** 新用户注册 */ this.socket.on(this.cxt.eventkeys.client.newmsg, function (msg) { /** 发送消息 */ self.notifymsg(msg) console.log(msg) self.cxt.addmsg(msg) }) this.socket.on(this.cxt.eventkeys.client.closeconn, function () { console.log(self.id + '--关闭连接') self.cxt.remove(self) }) this.sendusers() }
在初始化管道实例时做了如下事件:
- 将通讯socket添加一个到房间中,方便后期好广播消息
- 向当前连接上来的socket发送房间信息,设定为第一个房间
- 监听三个事件:用户注册、新消息、关闭连接。此处都要逻辑处理,可以参考源码。
客户端实现
主要实现连接服务、注册用户、发送和接受消息的功能。首先以main.js为入口,且需要先装配好vue相关配件,如vuex、elemui、客户端通讯管道等,然后创建vue实例和连接消息服务器,代码如下:
import '../node_modules/bootstrap/dist/css/bootstrap.css' import vue from 'vue' import elemui from 'element-ui' import 'element-ui/lib/theme-default/index.css' import app from './app' import * as stores from './store' import { keys } from './uitls' import { getcxt } from './services-client' let initroominfo = keys.setroominfo vue.use(elemui) /* eslint-disable no-new */ new vue({ store: stores.default, el: '#app', template: '<app/>', components: { app }, created: function () { let self = this getcxt().createio(this, function (roominfo) { stores.buscxt.init() /** 初始化view与service层的交互层(业务层) */ self.$store.dispatch(initroominfo, roominfo) getcxt().refusers(function (users) { stores.buscxt.usercxt.refusers(users) }) }) } })
一、与服务端的通讯
service-client目录中实例的与消息服务器通讯,其中包含创建用户、接受和发送消息等。一个客户端只能拥有一个消息管道,以下代码是消息管理的创建:
import * as io from 'socket.io-client' import context from './context' let eventkeys = require('../services-uitls/event.keys') let url = 'http://localhost:9001/' let cxt = null export function getcxt () { if (cxt == null) { cxt = new context(url, eventkeys, io) } return cxt }
在main.js中的vue实例的created勾子中调用了context的createio实例方法,用于创建一个与消息服务器的连接,并接受其中房间发送回来的房间信息。然后就初始化业务层。
二、vuex的结合
在store目录中实现,包含了vuex类相关的实现,还有业务层的实现。其中业务层会引用"客户端通讯管道",而vuex实现类有可能会引用业务层相关实现类,以此实现ui到"消息服务器"的通讯。 store/index.js代码如下:
import vuex from 'vuex' import vue from 'vue' import roomviewcxt from './room/roomviewcxt' import userviexcxt from './userviewcxt' import msgviewcxt from './msg/msgviewcxt' import buscxt from './indexforbus' let _buscxt = new buscxt() let _rvcxt = new roomviewcxt() let _uvcxt = new userviexcxt(_buscxt.usercxt) let _mvcxt = new msgviewcxt() let opt = { state: null, getters: null, mutations: null, actions: null } _rvcxt.use(opt) _uvcxt.use(opt) _mvcxt.use(opt) vue.use(vuex) let store = new vuex.store(opt) export default store export const buscxt = _buscxt /** 业务处理上下文 */ export function getbuscxt () { return _buscxt }
三、组件
组件只实现了 用户注册、主界面容器、消息发送和消息接受等。组件只会引用store目录中相关类,不会直接引用管道类。
- login.vue:用户注册组件
- hchat.vue:主界面容器组件
- message/msgwriter.vue:发送消息组件
- message/msglist.vue:接受和显示消息列表组件
如何运行实例
- cnpm run install 安装所有的依赖
- npm run sokcetio 启动消息服务器
- npm run dev 启动客户端
示例截图
下载地址:vue-socket_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 网站优化:站在做用户体验上做SEO 深度挖掘有价值的关键词
下一篇: PS简单制作一颗小药丸