vue + socket.io实现一个简易聊天室示例代码


Posted in Javascript onMarch 06, 2017

vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度。因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了。功能虽然不多,但还是有收获。设计和实现思路较为拙劣,恳请各位道友指正。

可以达到的需求

  • 能查看在线用户列表
  • 能发送和接受消息

使用到的框架和库

  • socket.io做为实时通讯基础
  • vuex/vue:客户端Ui层使用
  • Element-ui:客户端Ui组件

类文件关系图

服务端:

vue + socket.io实现一个简易聊天室示例代码

客户端:

vue + socket.io实现一个简易聊天室示例代码

服务端实现

实现聊天服务器的相关功能,包含通讯管道的创建、用户加入、消息的接受与转发等。

一、通讯服务建立

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.io实现一个简易聊天室示例代码

下载地址:vue-Socket_3water.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript入门教程(8) Location地址对象
Jan 31 Javascript
JQuery防止退格键网页后退的实现代码
Mar 23 Javascript
javascript 二进制运算技巧解析
Nov 27 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
Dec 13 Javascript
jQuery隐藏和显示效果实现
Apr 06 Javascript
AngularJS表格添加序号的方法
Mar 03 Javascript
bootstrap轮播图示例代码分享
May 17 Javascript
基于打包工具Webpack进行项目开发实例
May 29 Javascript
vue中引入第三方字体文件的方法示例
Dec 17 Javascript
实例讲解JavaScript预编译流程
Jan 24 Javascript
解决elementUI 切换tab后 el_table 固定列下方多了一条线问题
Jul 19 Javascript
vue3如何优雅的实现移动端登录注册模块
Mar 29 Vue.js
EasyUI为Numberbox添加blur事件的方法
Mar 05 #Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
Mar 05 #Javascript
js获取元素下的第一级子元素的方法(推荐)
Mar 05 #Javascript
Bootstrap模态框案例解析
Mar 05 #Javascript
video.js使用改变ui过程
Mar 05 #Javascript
Angular开发者指南之入门介绍
Mar 05 #Javascript
JavaScript自定义文本框光标
Mar 05 #Javascript
You might like
php中数组首字符过滤功能代码
2012/07/31 PHP
浅析PHP substr,mb_substr以及mb_strcut的区别和用法
2013/06/21 PHP
PHP目录操作实例总结
2016/09/27 PHP
laravel 5异常错误:FatalErrorException in Handler.php line 38的解决
2017/10/12 PHP
JavaScript OOP类与继承
2009/11/15 Javascript
JavaScript replace(rgExp,fn)正则替换的用法
2010/03/04 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
script不刷新页面的联动前后代码
2013/09/18 Javascript
Enter回车切换输入焦点实现思路与代码兼容各大浏览器
2014/09/01 Javascript
一款基jquery超炫的动画导航菜单可响应单击事件
2014/11/02 Javascript
$.extend 的一个小问题
2015/06/18 Javascript
JS传值出现中文参数乱码的解决方法
2016/06/30 Javascript
微信小程序前端源码逻辑和工作流
2016/09/25 Javascript
微信小程序-滚动消息通知的实例代码
2017/08/03 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
js实现图片上传并预览功能
2018/08/06 Javascript
p5.js绘制创意自画像
2019/11/04 Javascript
jQuery开发仿QQ版音乐播放器
2020/07/10 jQuery
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
Python Web框架Flask下网站开发入门实例
2015/02/08 Python
如何使用 Pylint 来规范 Python 代码风格(来自IBM)
2018/04/06 Python
python requests抓取one推送文字和图片代码实例
2019/11/04 Python
Python实现大数据收集至excel的思路详解
2020/01/03 Python
Python使用pyenv实现多环境管理
2021/02/05 Python
基于html和CSS3制作酷炫的导航栏
2015/09/23 HTML / CSS
德国最大的服装、鞋子和配件在线商店之一:Outfits24
2019/07/23 全球购物
BannerBuzz加拿大:在线定制横幅印刷、广告和标志
2020/03/10 全球购物
新闻人物通讯稿
2014/10/09 职场文书
文明单位创建材料
2014/12/24 职场文书
初中教师个人总结
2015/02/10 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
学校就业保障协议书
2019/06/24 职场文书
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle