最近了解了一下socket,所谓socket,就是基于TCP的全双工通信,通信双方在建立连接后可以在任何时候都能发送数据,感觉还是挺有意思的,不过话又说回来了,socket在生活中的使用还是挺普遍的,像最普遍的QQ和微信,在比如一些网游,都是基于socket实现的,既然了解了,所以就打算做一个基于socket的实时通信的简单应用,话不多说,先上截图
进入后首先需要输入姓名或昵称,至于为什么就不多说了。
当有新人进入后,就会收到提示,某某某来吃瓜了。
当收到消息,便可以显示,这里需要补充一下,因为只是实现了基本的功能,就没做那么多样式,即使是自己发的消息也是是在左侧显示(我是谁发的这条消息是本人发的)
到这里截图就结束了哈哈,好吧,看着是有些简陋,下面就说一下是怎么实现的
服务端
1、安装express和socket.io模块
npm install express
npm install socket.io
2、代码
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var express=require('express')
//设置静目录
app.use('/socket',express.static('./public'))
//解决跨域问题
app.all('*',function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
if (req.method == 'OPTIONS') {
res.send(200); /* 让options请求快速返回*/
}
else {
next();
}
});
//socket连接
io.on('connection', (socket) => {
console.log('a user connected');
// socket.broadcast.emit('newPeer','new');
//将收到的消息广播出去
socket.on('sendMessage', function(content){
console.log(content); //content为收到的消息内容,包括姓名和消息内容
socket.broadcast.emit('getMessage',content);
});
//监听新人连接,然后广播出去
socket.on('newPeople', function(name){
console.log(name) //name为连接者的姓名或昵称
socket.broadcast.emit('newPeer',name);
});
});
//将vue项目打包成h5后,发起请求将html文件返回
app.get('/socket', (req, res) => {
res.sendfile('./index.html')
});
http.listen(3030, () => {
console.log('listening on *:3030');
});
其中:
io.on('connection', (socket) => {
console.log('a user connected');
});
该函数是用来监听连接的,每当有新的设备连接,都会执行里面相应的语句,同时回调函数返回的参数socket
用来发送消息,比如:
socket.broadcast.emit('getMessage','hello');
会向除本次连接的或发送消息的人外所有人发送消息hello
getMessage
为相应的事件名,客户端也需要用这个名字才可以接收到hello
这条内容。
socket.io的一些其他用法可以查看这篇文章 socket的基本使用
也可以去官网了解更多
客户端
1、安装weapp.socket.io
npm install weapp.socket.io
为了方便发行,我采取的做法是,执行完上面的指令后,去node_modules
文件夹中将weapp.socket.io.js
文件拿出来放在一个单独的文件夹中引入,当然,可以因人而异。
如果想了解weapp.socket.io
,可以前往了解
2、引入weapp.socket.io.js
在main.js中引入
import io from 'common/weapp.socket.io.js' //根据自己weapp.socket.io.js文件的路径来写
Vue.prototype.socket=io('http://192.168.1.192:3030') //全局变量,根据自己node服务的ip地址和端口号来写,也就是本机ip
3、代码
<template>
<view class="page">
<view class="messages">
<view class="content" v-for="(item,index) in list" :key='index'>
<text class="name">{{item.name}}: </text>
<text class="msg">{{item.msg}}</text>
</view>
</view>
<!-- 遮掩层,提示输入姓名 -->
<u-mask :show="show">
<view class="tip">
<input class="inputName" v-model="name" placeholder="姓名或昵称" />
<button class="submitName" @click="onSubmitName">提交</button>
</view>
</u-mask>
<view class="send">
<input class="input" placeholder="输入内容,点击发送" v-model="content" />
<button class="submit" @click="send()">发送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
show: true,
name: '',
list: [{
"name": 'tip',
"msg": 'The first content!'
}],
content: ''
}
},
onLoad() {
this.socket.on('connect', () => {
console.log('connection created.')
});
if (this.name) {
this.show = false
}
//监听广播消息
this.getMsg()
},
methods: {
//提交姓名
onSubmitName: function() {
console.log(this.name)
if (this.name) {
this.show = false
this.socket.emit('newPeople', this.name);
}
},
//发送消息
send: function() {
if (this.content) {
this.list.push({
"name": this.name,
"msg": this.content
})
console.log(this.list)
this.socket.emit('sendMessage', {
"name": this.name,
"msg": this.content
});
this.content = ''
uni.pageScrollTo({
duration: 0,
scrollTop: this.list.length * 100
})
} else {
uni.showToast({
title: '请输入内容',
icon: 'none'
})
}
},
//接收消息
getMsg: function() {
//接收广播消息
this.socket.on('getMessage', (content) => {
console.log(content)
this.list.push(content)
uni.pageScrollTo({
duration: 0,
scrollTop: this.list.length * 200
})
});
//接收有新人连接的消息
this.socket.on('newPeer', (name) => {
console.log(name)
uni.showToast({
title: name + '来吃瓜了。。'
});
// this.list.push(data)
});
}
}
}
</script>
<style>
page {
width: 750rpx;
/* height: 2000px; */
background-color: #f3f4f5;
}
.page {
width: 100%;
}
/* 遮掩层 */
.tip {
width: 400rpx;
height: 400rpx;
padding: 40rpx;
background-color: white;
margin: 300rpx auto;
border: 1rpx solid white;
border-radius: 40rpx;
}
.inputName {
width: 250rpx;
/* height: 80rpx; */
margin: 40rpx 0;
padding: 20rpx;
border: 1rpx solid #007AFF;
border-radius: 40rpx;
}
.submitName {
width: 300rpx;
height: 80rpx;
margin: 100rpx 0 0;
color: white;
background-color: #007AFF;
}
.messages {
width: 710rpx;
margin: 0rpx auto 300rpx;
}
.content {
width: 100%;
display: flex;
/* flex-direction: column; */
align-items: center;
justify-content: flex-start;
}
.name {
margin-right: 10rpx;
}
.msg {
/* display: flex;
flex-wrap:wrap; */
background-color: white;
padding: 20rpx;
border: 1rpx solid white;
border-radius: 20rpx;
margin: 20rpx 0 0;
word-wrap: break-word;
word-break: break-all;
}
.send {
position: fixed;
bottom: 0;
}
.input {
width: 710rpx;
padding: 20rpx;
border: 1px solid #e8e8e8;
border-radius: 20rpx;
}
.submit {
color: white;
background-color: #007AFF;
}
</style>
这里一定要切记一件事
因为我使用了uView组件库,如果想直接使用我的代码,也必须引入这个组件库才可以,具体操作可以查看官网的快速上手
如果只是要实现相应的功能,只需记住使用下面两个函数
//接收消息,第一个参数为事件名,须与服务端对应,第二个是回调函数,回调中的参数是接收来的消息内容
this.socket.on('newPeer', (name) => {
console.log(name)
});
//发送消息,第一个参数为事件名,须与服务端对应,第二个是要发送的值
this.socket.emit('newPeople', this.name);
总结
大致过程就是这样了,自己也是个小白,如果有什么说错的地方也欢迎大佬指出。