32 websocket通讯实现

32 websocket通讯实现

写在前面:

php服务端使用的是已经封装好了的workman实现websocket服务端功能

uniapp客户端使用的是uniapp内置的showcketTask api 实现websocket客户端功能

换句话说用的都是别人已经封装好的了

如果想深入研究建议参考 炎龙的 智能玩具websocket部分视频

一 通讯原理

image-20200514175121535

1 客户端wss请求连接,服务端返回建立连接成功

2 服务端wss向客户端发送客户端的id,并且告诉客户端需要绑定

{
	"type": "bind",
	"data": "7f0000010b5700000004"
}

3 客户端带着自己的user_id ,ajax请求服务端绑定

4 服务端以后根据user_id 向绑定了该user_id 的所有客户端进行发送信息。

5 客户端wss绑定user_id成功后:

  • 关于即时通讯功能,以后wss只用于接受服务端的信息

  • 客户端以后依旧使用ajax向服务端提交即时通讯信息。

精炼:websocket只接受连接并不接受通讯内容。通过http来的通讯内容经过websoket推送给具体的user_id

二 服务端接口

wss )1 监听websocket连接,并且给其返回连接成功,并且再发一条(客户端id,并且要求绑定。)

(http)2 绑定上线,监听客户端请求绑定user_id。

(http)3 接受客户端要发送的聊天内容

  • 如果发送内容的收件人在线wss直接发送信息给收件人,http返回ok。 (ps:该php后端并没有存储到数据库中)。
  • 如果发送内容的收件人不在线直接缓存到redis里面,http返回ok。 (ps:该php后端并没有把聊天内容存储到数据库中)。

(http)4 判断用户是否在线,从缓存里直接拿出来缓存的未读信息,然后直接给客户端返回。

三 客户端

1 没有登录成功

  • 不触发socket事件

2 登录成功后

  • 打开socket
  • 监听服务端消息
  • 绑定用户
  • http查看不在线未读消息
  • 更新通讯列表,更新与人通讯详情列表,更新未读数下角标

3 app开启的时候,并且已经登录了(绑定服务端+读取未读消息)

  • 打开socket
  • 监听服务端消息
  • 绑定用户
  • http查看不在线未读消息
  • 更新通讯列表,更新与人通讯详情列表,更新未读数下角标

4 app开启的时候,并且已经登录了(开始接受消息)

ps:getter来处理未读数量问题,好处待定。

一 用户不操作的情况

  • 监听服务端消息。
  • Index根据ToUser,判断是否正在根这个人聊天
  • 第一种:如果和这个人正在聊天,
    • 1 userchat页面$on接受到VUEX传来的信息进行渲染
    • 2 不用更新下角标未读数。
    • 3 更新state里面的两个通讯表
    • 4 更新本地通讯列表
    • 5 更新本地与人通讯详情列表
  • 第二种:如果和这个人没有正在聊天(也就是ToUser为空,并且意味着user-chat关闭的)
    • 1 更新下角标未读数。
    • 2 更新本地通讯列表
    • 3 更新本地与人通讯详情列表

二 用户操作的情况

用户察觉到了未读下角标,然后点击该通讯列表的某人:

  • 1 action然后点开页面清空下角标。
  • 2 action然后打开页面加载与人通讯详情列表,渲染页面。

5 登录了,app已经打开了(发送消息)

  • 一定是打开了与某人聊天的页面。
  • 然后触发submit事件。
  • action里面更新与某个用户的消息记录并存储到本地。
  • action里面更新用户通讯表并存储到本地。
  • 返回格式化好的数据,http发送到服务端。
  • 把发送的信息渲染到与这个人聊天页面。

四 插播async+await

精华:

// 案例:
async xxxx(){
	  setTimeout(()=>{
      console.log('settimeout内部谁都没有等我')
    },4000)
    console.log('xxxx说我并不会等setTimeout')
}
	
async f1(){
  await xxxx() 
  console.log('f1输出')
}

f1()
// 输出:
// xxxx说我并不会等setTimeout
// f1输出
// settimeout内部谁都没有等我

            
				// await xxxx() 
				// await只能保证xxx()产生的promise对象等到了resolve拿到了返回结果(站在函数的角度就是产生了执行到了return)
				// 但是await并不能保证xxx()函数体里面的异步代码也会执行完,
				// 如果想要保证xxx()里面的异步代码也执行完了,需要在xxxx函数内部定制await。
				
				//  xxxx()不写await, 直接返回一个promise对象,并不会在此刻等到执行完函数体代码。
				
				
				
// **精炼**:await 能保证promise拿到resolve,不能保证await的async函数内部异步执行完。

案例:

<template>
	<view>
		<!-- 测试foreach -->
		<!-- <view class="font" click="testList">测试{{list}}</view> -->
		
		<!-- 测试web-view -->
		<!-- <web-view src="/hybrid/html/dongxiao2/index.html" @message="getMes
		sage"></web-view> -->
		
		<button type="default" class="bg-main text-white rounded" style="width: 500rpx;"  @click="func1">点我测试async+await</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// list : [4,3,2,1]
				
			}
		},
		methods: {
			getMessage(e){
				console.log(e)
			},
			testList(){
				
			},
			async func1(){
				console.log('func1')
				await this.func2() 
				// func2本身是个异步函数,也就是func2加括号执行直接返回个promise对象。
				// 如果不写await 直接返回promise对象,并不会等到promise里面的resolve,也就是并不会等到函数体的同步代码执行到最后一行,也就是不会等到return执行。
				// 如果写了await 那么就会等到这个func2的promise对象产生了resolve拿到值,继续往下执行,也就意味着async func2会”完整“执行一遍
				// 前方高能:坑来了!!!!
				
				// 上面提到的“完整”打了引号证明是不对的,注意:那是否可以理解await作用下的 func2已经完整执行完了?答案是错!!!!
				// 来 跟我把视角定位async func2 函数体代码。
				// 思考如下代码func2体里面有异步代码this.func4(),当这个异步只是返回promise对象,就接着往下执行console.log('func2')
				// 并没有等到this.func4()的该promise对象拿到resolve。
				// 也就是func2里的this.func4()这个异步还没有执行完,就已经开始执行了fun1()里的this.func3()
				
				// 结论:
				// 所以await xxxx() 
				// await只能保证xxx()产生的promise对象等到了resolve拿到了返回结果(站在函数的角度就是产生了执行到了return)
				// 但是await并不能保证xxx()函数体里面的异步代码也会执行完,
				// 如果想要保证xxx()里面的异步代码也执行完了,需要在xxxx函数内部定制await。
				
				//  xxxx()不写await, 直接返回一个promise对象,并不会在此刻等到执行完函数体代码。
				
				// **精炼**:await 能保证promise拿到resolve,不能保证await的async函数内部异步执行完。
				
				
				// 执行结果如下:
				// 12:59:04.539 func1 at pages/test2/test2.vue:30
				// 12:59:04.562 func2 at pages/test2/test2.vue:37
				// 12:59:04.586 func3 at pages/test2/test2.vue:41
				// 12:59:06.546 func4 at pages/test2/test2.vue:45
				// 12:59:07.538 func5 at pages/test2/test2.vue:51
			
				
				// 要明白这样只会让func2的代码完整执行完,不会让func2里面的异步代码
				await this.func3()
				
			},
			async func2(){
				this.func4()
				console.log('func2')
			},
			async func3(){
				this.func5()
				console.log('func3')
			},
			async func4(){
				setTimeout(()=>{
					console.log('func4')
				},2000)
				
			},
			async func5(){
				setTimeout(()=>{
					console.log('func5')
				},3000)
			},
			
			
			
			
			
			
		}
	}
</script>

<style>

</style>

posted @ 2020-05-25 18:46  张明岩  阅读(226)  评论(0编辑  收藏  举报