iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
1
Software Development

線上娃娃機-js開發篇系列 第 4

線上娃娃機-後端功能

  • 分享至 

  • xImage
  •  

server part 功能包括

typeorm 的 orm entity 規劃資料表與orm使用

https://typeorm.io/#/

apolloServer type graphql 的設計與 實作 query 與 mutation
(如果沒有使用過graphql的朋友可以想做打api格式跟實作回應的就可以了)

http://apollographql.com/

passport 第三方認證登入 並發出 jwt token,娃娃機 目前有用到的是fb 與 google 模式

http://www.passportjs.org/

片段程式說明 以fb為例 先去申請一組 app https://developers.facebook.com/
需要 clientID與SECRET

import FacebookStrategy from 'passport-facebook';
import express from 'express'

...略 express setup
passport.use(
        new FacebookStrategy.Strategy(
            { clientID: clientID, clientSecret: SECRET, callbackURL: 'https://clawfun.online/callbackurl', profileFields: ['id', 'email', 'displayName', 'photos'] },
            async (accessToken: any, refreshToken: any, profile: any, cb: any) => {
                const { id, displayName, _json } = profile;
                return cb(null, { member: profile, accessToken, refreshToken });
            },
        ),
    ); 
//express
 app.get('/callbackurl',
        passport.authenticate('facebook', { session: false }),
        async (req: any, res) => {
            const member = _.get(req, 'user.profile')
            const accessToken = _.get(req, 'user.accessToken');
            const refreshToken = _.get(req, 'user.refreshToken');
            try {
                const createJwtToken = await createTokens(req, member, SECRET); 
                res.redirect(`https://clawfun.online`);
            } catch (err) {
                res.redirect(`https://clawfun.online/fbauthfail`);
            }
        },
    );

//簽Jwt 範例

export const createTokens = async (req: any, member: any, secret: any) => {
    const tokenInfo = jwt.sign(member, secret, { expiresIn: '365d', });
     return tokenInfo
};


ffmpeg 轉檔 當遊玩娃娃時候會開始錄影 當結束後會由 ts檔案 轉mp4檔案 讓使用者方便在前端瀏覽
稍後章節會在解說這個部分的程式碼
https://github.com/fluent-ffmpeg/node-fluent-ffmpeg

第三方金流 tappay 選用原因之一是他是可以不用轉跳頁面 使用者體驗更佳,在之後章節會再提一些開發心得

http://tappaysdk.com/

接受前端的api 後 ,根據條件發指令給娃娃機的溝通 ,所有結果 有分通知個人 與通知全部或是特定條件
所以這邊會用到 websocket 與 apollo subscribe

後端 apollo server 主要設定片段

  const server = new ApolloServer({
        schema: genSchema(), uploads: { maxFileSize: 10000000, maxFiles: 20 },
        context: async ({ req }: { req: any }) => {
            const tokenInfo = await jwtwork(req); return { ...tokenInfo, req, connection, allMachines, machineMap, pubsub }
        },
        tracing: false,
        debug: false,
         introspection: false,
         subscriptions: {   
            onConnect: (connectionParams, webSocket, context) => {  
            ...
            },
            onDisconnect: (webSocket, context) => {
            ...
            },
        },
    })

    server.applyMiddleware({ app, cors: { credentials: true, origin }, })

    const httpServer = http.createServer(app);
    server.installSubscriptionHandlers(httpServer);

    httpServer.listen({ port: 5002 }, () => {
        console.log(`? GraphQl Server at 開發環境 is    http://localhost:5002${server.graphqlPath}`);
        console.log(`? GraphQl Server Subscriptions is  ws://localhost:5002${server.subscriptionsPath}`)

    })

除了與前端對接之外也要與娃娃機的 relay 機器對接 (娃娃機會自己把一些指令集傳到relay這台機等待被呼叫,relay機器要自己架設)
對街的資料要透過socket

大概做法例如傳一個指令集(

  conn = net.createConnection(configs.SOCKET_PORT, configs.SOCKET_HOST);
  ...省略
    machine.socket=conn
    const header = Buffer.from([1]);
    const id = Buffer.from(machine.wawajiId + ';');
    const command = Buffer.from(wawajiControl.getCommand(cameraId, cmdId));
    machine.socket.write(Buffer.concat([header, id, command]));

這邊的header 要根據娃娃機板子提供的規格去制定 後面的章節再詳細說明 這邊先提個大概

以上就大概是後端功能


上一篇
線上娃娃機-硬體環境介紹
下一篇
線上娃娃機-前端功能介紹
系列文
線上娃娃機-js開發篇11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言