diff options
| author | Akihiko Odaki <nekomanma@pixiv.co.jp> | 2018-03-29 01:20:40 +0900 |
|---|---|---|
| committer | Akihiko Odaki <nekomanma@pixiv.co.jp> | 2018-03-29 01:54:41 +0900 |
| commit | 90f8fe7e538bb7e52d2558152a0390e693f39b11 (patch) | |
| tree | 0f830887053c8f352b1cd0c13ca715fd14c1f030 /src/server/api/streaming.ts | |
| parent | Implement remote account resolution (diff) | |
| download | sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.tar.gz sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.tar.bz2 sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.zip | |
Introduce processor
Diffstat (limited to 'src/server/api/streaming.ts')
| -rw-r--r-- | src/server/api/streaming.ts | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts new file mode 100644 index 0000000000..95f444e00b --- /dev/null +++ b/src/server/api/streaming.ts @@ -0,0 +1,118 @@ +import * as http from 'http'; +import * as websocket from 'websocket'; +import * as redis from 'redis'; +import config from '../../conf'; +import { default as User, IUser } from './models/user'; +import AccessToken from './models/access-token'; +import isNativeToken from './common/is-native-token'; + +import homeStream from './stream/home'; +import driveStream from './stream/drive'; +import messagingStream from './stream/messaging'; +import messagingIndexStream from './stream/messaging-index'; +import othelloGameStream from './stream/othello-game'; +import othelloStream from './stream/othello'; +import serverStream from './stream/server'; +import requestsStream from './stream/requests'; +import channelStream from './stream/channel'; + +module.exports = (server: http.Server) => { + /** + * Init websocket server + */ + const ws = new websocket.server({ + httpServer: server + }); + + ws.on('request', async (request) => { + const connection = request.accept(); + + if (request.resourceURL.pathname === '/server') { + serverStream(request, connection); + return; + } + + if (request.resourceURL.pathname === '/requests') { + requestsStream(request, connection); + return; + } + + // Connect to Redis + const subscriber = redis.createClient( + config.redis.port, config.redis.host); + + connection.on('close', () => { + subscriber.unsubscribe(); + subscriber.quit(); + }); + + if (request.resourceURL.pathname === '/channel') { + channelStream(request, connection, subscriber); + return; + } + + const user = await authenticate(request.resourceURL.query.i); + + if (request.resourceURL.pathname === '/othello-game') { + othelloGameStream(request, connection, subscriber, user); + return; + } + + if (user == null) { + connection.send('authentication-failed'); + connection.close(); + return; + } + + const channel = + request.resourceURL.pathname === '/' ? homeStream : + request.resourceURL.pathname === '/drive' ? driveStream : + request.resourceURL.pathname === '/messaging' ? messagingStream : + request.resourceURL.pathname === '/messaging-index' ? messagingIndexStream : + request.resourceURL.pathname === '/othello' ? othelloStream : + null; + + if (channel !== null) { + channel(request, connection, subscriber, user); + } else { + connection.close(); + } + }); +}; + +/** + * 接続してきたユーザーを取得します + * @param token 送信されてきたトークン + */ +function authenticate(token: string): Promise<IUser> { + if (token == null) { + return Promise.resolve(null); + } + + return new Promise(async (resolve, reject) => { + if (isNativeToken(token)) { + // Fetch user + const user: IUser = await User + .findOne({ + host: null, + 'account.token': token + }); + + resolve(user); + } else { + const accessToken = await AccessToken.findOne({ + hash: token + }); + + if (accessToken == null) { + return reject('invalid signature'); + } + + // Fetch user + const user: IUser = await User + .findOne({ _id: accessToken.user_id }); + + resolve(user); + } + }); +} |