ws
This commit is contained in:
		
							
								
								
									
										71
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								README.md
									
									
									
									
									
								
							@@ -84,6 +84,77 @@ fetch('/user', {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 登录会话
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					fetch('/session', {
 | 
				
			||||||
 | 
					    method: 'POST',
 | 
				
			||||||
 | 
					    headers: { 'Content-Type': 'application/json' },
 | 
				
			||||||
 | 
					    body: JSON.stringify({
 | 
				
			||||||
 | 
					        name: 'Kana',
 | 
				
			||||||
 | 
					        password: '00000000'
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					}).then(Response => Response.json()).then(data => {
 | 
				
			||||||
 | 
					  console.log(data)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 会话列表
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					fetch('/session', {
 | 
				
			||||||
 | 
					    method: 'GET',
 | 
				
			||||||
 | 
					}).then(Response => Response.json()).then(data => {
 | 
				
			||||||
 | 
					  console.log(data)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sid: 'xxxxxsid',
 | 
				
			||||||
 | 
					        uid: 'xxxxxuid',
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### 注销会话
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					注销当前会话
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					fetch('/session', {
 | 
				
			||||||
 | 
					    method: 'DELETE',
 | 
				
			||||||
 | 
					}).then(Response => Response.json()).then(data => {
 | 
				
			||||||
 | 
					  console.log(data)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					注销指定会话
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					fetch('/session/xxxxxsid', {
 | 
				
			||||||
 | 
					    method: 'DELETE',
 | 
				
			||||||
 | 
					    headers: { 'Content-Type': 'application/json' },
 | 
				
			||||||
 | 
					    body: JSON.stringify({
 | 
				
			||||||
 | 
					        name: 'Kana',
 | 
				
			||||||
 | 
					        password: '00000000'
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					}).then(Response => Response.json()).then(data => {
 | 
				
			||||||
 | 
					  console.log(data)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### 修改资料
 | 
					#### 修改资料
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										87
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								index.js
									
									
									
									
									
								
							@@ -7,14 +7,8 @@ import random from 'string-random'
 | 
				
			|||||||
import formidable from 'formidable'
 | 
					import formidable from 'formidable'
 | 
				
			||||||
import md5 from 'md5-node'
 | 
					import md5 from 'md5-node'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//process.on('SIGINT', function () {
 | 
					 | 
				
			||||||
//  console.log('Got SIGINT.  Press Control-D/Control-C to exit.')
 | 
					 | 
				
			||||||
//  process.exit(0)
 | 
					 | 
				
			||||||
//})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const app = expressWs(express()).app
 | 
					const app = expressWs(express()).app
 | 
				
			||||||
const databases = new Map() // 所有数据库
 | 
					const databases = new Map() // 所有数据库
 | 
				
			||||||
//const wsstores = new Map() // 所有 websocket 连接
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const db = (name) => (databases.get(name) || function () {
 | 
					const db = (name) => (databases.get(name) || function () {
 | 
				
			||||||
  let database = new nedb({ filename: `./data/db/${name}.db`, autoload: true, timestampData: true })
 | 
					  let database = new nedb({ filename: `./data/db/${name}.db`, autoload: true, timestampData: true })
 | 
				
			||||||
@@ -22,13 +16,6 @@ const db = (name) => (databases.get(name) || function () {
 | 
				
			|||||||
  return database
 | 
					  return database
 | 
				
			||||||
}())
 | 
					}())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 通道: 自动构建 ws 列表
 | 
					 | 
				
			||||||
// const wsstore = name => (wsstores.get(name) || function () {
 | 
					 | 
				
			||||||
//   let list = new Map()
 | 
					 | 
				
			||||||
//   wsstores.set(name, list)
 | 
					 | 
				
			||||||
//   return list
 | 
					 | 
				
			||||||
// }())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const session_store = sessionDb(session, db('session'))
 | 
					const session_store = sessionDb(session, db('session'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 登录验证
 | 
					// 登录验证
 | 
				
			||||||
@@ -52,6 +39,80 @@ const user_load = async (_id) => await new Promise(resolve => db('user').findOne
 | 
				
			|||||||
  return resolve(user)
 | 
					  return resolve(user)
 | 
				
			||||||
}))
 | 
					}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const HUB = class {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    this.频道 = new Map() // fid: [uid]
 | 
				
			||||||
 | 
					    this.用户 = new Map() // uid: [ws]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  增加会话(uid, ws) {
 | 
				
			||||||
 | 
					    this.用户(uid).push(ws) // 必须验证是数组
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  增加频道(fid) {
 | 
				
			||||||
 | 
					    this.频道.set(fid, [])
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  订阅频道(fid, uid) {
 | 
				
			||||||
 | 
					    this.频道(fid).push(uid) // 必须验证是数组
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  取消订阅(fid, uid) {
 | 
				
			||||||
 | 
					    this.频道(fid).filter(item => item != uid)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  发送消息(fid, data) {
 | 
				
			||||||
 | 
					    this.频道(fid).forEach(uid => {
 | 
				
			||||||
 | 
					      this.用户(uid).forEach(ws => {
 | 
				
			||||||
 | 
					        ws.send({ fm: fid, data })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  移除会话(uid, ws) {
 | 
				
			||||||
 | 
					    this.用户(uid).filter(item => item != ws)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  移除频道(id) {
 | 
				
			||||||
 | 
					    this.频道.delete(id)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  移除用户(uid) {
 | 
				
			||||||
 | 
					    this.频道.filter(item => item != uid)        // 取消用户所有订阅
 | 
				
			||||||
 | 
					    this.用户.get(uid).forEach(ws => ws.close()) // 断开用户所有会话
 | 
				
			||||||
 | 
					    this.用户.delete(uid)                        // 删除用户(所有会话)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const FM = new HUB()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 通讯频道 Frequency Modulation
 | 
				
			||||||
 | 
					function webscoketer(ws, req) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 验证身份已经登录
 | 
				
			||||||
 | 
					  if (!req.session.account) return ws.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 将连接加入到列表
 | 
				
			||||||
 | 
					  FM.增加会话(req.session.account.uid, ws)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 当用户连接时, 读取其订阅列表
 | 
				
			||||||
 | 
					  db('user').findOne({ uid: req.session.account.uid }, function (err, doc) {
 | 
				
			||||||
 | 
					    if (doc && Array.isArray(doc.fm)) {
 | 
				
			||||||
 | 
					      doc.fm.forEach(fid => FM.订阅频道(fid, req.session.account.uid))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 收到消息时(只有频道消息)
 | 
				
			||||||
 | 
					  ws.on('message', function (msg) {
 | 
				
			||||||
 | 
					    // 可能需要检查权限, 是否可以向指定目标发送, 或者由客户端过滤
 | 
				
			||||||
 | 
					    // 还需要在 data 中附带上发送者信息
 | 
				
			||||||
 | 
					    let { fid, data } = msg
 | 
				
			||||||
 | 
					    FM.发送消息(fid, data)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 关闭连接时
 | 
				
			||||||
 | 
					  ws.on('close', function (code) {
 | 
				
			||||||
 | 
					    FM.移除会话(req.session.account.uid, ws)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 发生错误时
 | 
				
			||||||
 | 
					  ws.on('error', function (code) {
 | 
				
			||||||
 | 
					    console.log('link error: ', code)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 会话列表
 | 
					// 会话列表
 | 
				
			||||||
function session_list(req, res) {
 | 
					function session_list(req, res) {
 | 
				
			||||||
  return session_store.db.find({ "data.account.uid": req.session.account.uid }, function (err, docs) {
 | 
					  return session_store.db.find({ "data.account.uid": req.session.account.uid }, function (err, docs) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user