Aizhi EdgerOSの詳細な分析 Socket.IOを使用してAizhiアプリケーションで双方向通信を簡単に実現する方法

1. Socket.IO とは?

  • Socket.IO は、イベント通信に基づくリアルタイム アプリケーション フレームワークであり、インスタント メッセージング、通知とメッセージ プッシュ、リアルタイム分析、およびその他のシナリオで広く使用されています。
  • Socket.IO は、次の 2 つの部分で構成されています。
    • サーバー側のモジュール (JSRE は socket.io モジュールを提供しています)。
    • クライアント側のモジュール。
  • Socket.IO は、実装を 2 つのレイヤーに分割します。
    • 基礎となるパイプライン: Socket.IO の内部エンジンである Engine.IO 層。
    • 高レベル API: つまり、Sokcet.IO 自体。
  • Engine.IO は、サーバーとクライアント間の低レベルの接続を確立する役割を担い、その主なタスクは、さまざまな転送とアップグレードのメカニズム、および切断の検出と再接続を処理することです。クライアントは最初に WebSocket 経由で接続を試みますが、失敗すると長いポーリングのために HTTP にフォールバックします。したがって、理想的には、次のことが保証されている必要があります。
    • ブラウザは WebSocket をサポートしています。
    • クライアントとサーバー間の WebSocket 接続をブロックする要素 (プロキシ、ファイアウォールなど) はありません。
  • 接続が確立されると、上位層は公開された API を介してデータを交換できます。

2. 高レベル API

  • Socket.IO はイベントベースであり、実際には EventEmitter クラスの継承であり、オブジェクト (エミッター) が名前付きイベントを発行し、関数オブジェクト (リスナー) が呼び出されます。イベント ドリブンに基づいて、on メソッドを介してイベント名とリスナー関数をリスナーに追加し、emit を介してリスナー関数をトリガーして通信タスクを完了する必要があります。
  • Socket.IO は、基本的な on()、emit()、removeListener() などを含む EventEmitter のイベント トリガーおよびリスニング関数を実装し、次のような接続ライフ サイクルのいくつかのイベント名もカスタマイズします。
    • connect は、クライアントが接続したときにトリガーされます。
    • connection は connect の別名です。
    • disconnect 接続が切断されたときにトリガーされます。
    • disconnecting クライアントが切断しようとしている (ルームを離れていない) ときにトリガーされます。
    • error エラーが発生したときに発生します。
  • これらは Socket.IO (および newListener、removeListener) の予約済みフィールドであり、カスタマイズ時にこれらのフィールドと名前が重複しないようにする必要があります。

3. JSRE の参照

  • JSREはSocket.IOのモジュールを提供しており、サーバー側で直接利用することができます.JSREでのSocket.IOの現在のバージョンは2.xであり、フロントエンドはバージョン対応に注意する必要があります. Socket.IO モジュールを使用します。
  • では、Socket.IO はどのように機能するのでしょうか?

第四に、サーバー側の作成

  • 以下に示すように、サーバー側のサンプル コードです。
/* Import system modules */
const WebApp = require('webapp');
const io = require('socket.io');

/* Import routers */
const myRouter = require('./routers/rest');

/* Create App */
const app = WebApp.createApp();

/* Set static path */
app.use(WebApp.static('./public'));

/* Set test rest */
app.use('/api', myRouter);

/* Rend test */
app.get('/temp.html', function(req, res) {
    
    
  res.render('temp', {
    
     time: Date.now() });
});

/* Start App */
app.start();

const socketio = io(app, {
    
    
  serveClient: false,
  pingInterval: 10000,
  pingTimeout: 5000
})

socketio.on('connection', socket => {
    
    
  console.log('>> socket connected <<')
  socket.emit('falcon', 'reply please')

  socket.on('message', (data, ack) => {
    
    
    console.log('recive:', data)
    ack('0')
  })

  socket.on('message2', data => {
    
    
    console.log('recive:', data)
  })
})


/* Event loop */
require('iosched').forever();
  • ご覧のとおり、Socket.IO サーバーを作成するのは非常に簡単です.webapp のインスタンスをパラメーターとして渡し、接続方法を監視するだけです。emit はメッセージを発行し、メッセージの内容は必要に応じて定義できます. 単純な文字列または構造化された JSON オブジェクトにすることができます.
  • 上記の例のように、socket.on でリッスン メッセージ フィールドを定義します。データを受信して​​処理するか、ack を指定して確認情報を返すことしかできません。socket.emit は、確認応答を行うための response の return 関数もサポートしています。
socket.emit('ferret', 'tobi', (data) => {
    
    
  console.log(data); // data will be 'woot'
});

// client code example
client.on('ferret', (name, fn) => {
    
    
  fn('woot');
});

5. クライアントの作成

  • 次に、フロントエンド アプリケーションが Socket.IO を使用して接続を確立し、サーバーと通信する方法を見てみましょう. Vue3 を例として、socket.io-client パッケージを使用します。
npm install socket.io-client
# or use yarn 
yarn add socket.io-client
  • 別のページでの呼び出しを容易にするために、socket.io を一度カプセル化することができます。以下は参照用です。
// src/libs/socketio.js
import io from 'socket.io-client'
class SocketIO {
    
    
  constructor () {
    
    
    this.socket = io('https://192.168.128.1:7369')
    this.socket.on('connect', () => {
    
    
      // 连接上服务端的回调函数
      // 还可以监听 'error' 并对错误连接进行相应处理
      console.log('>> 已连接!')
    })
  }

  push (event, msg) {
    
    
    // 这里封装了一个通用 response 的 emit 方法用以处理相同确认操作的 emit
    this.socket.emit(event, msg, (response) => {
    
    
      console.log('>>>> res:', response)
    })
  }
}

export const socketio = new SocketIO()

6. クライアント接続のライフサイクル

  • ライフサイクルの概略図:

ここに画像の説明を挿入

  • 次に、簡単な操作のために別のページでこのパッケージを参照できます。
// src/App.jsx
import {
    
     defineComponent, onMounted } from 'vue'
import './app.less' // css 设置白色背景及安全距离
// 上文中导出的 socketio
import {
    
     socketio } from './libs/socketio'

export default defineComponent({
    
    
  name: 'APP',
  setup (props, ctx) {
    
    
    //
    onMounted(() => {
    
    
      // 如果此页面需要监听后端发送数据
      // 最好将监听函数在 onMounted 生命周期中创建出来
      socketio.socket.on('message', data => {
    
    
        console.info('>> client recive:', data)
      })
    })

    // 发送数据的函数
    function handleEmitMsg () {
    
    
      socketio.push('message', 'gg')
    }
    return () => (
      <div>
        <p><button onClick={
    
     handleEmitMsg }>emit</button></p>
      </div>
    )
  }
})
  • 以上がフロントエンドの監視メッセージとメッセージ送信の操作ですが、このとき特定の操作に対して送信メッセージの返信確認を実行したい場合は、以下の例で取得できます。
// 修改上例中的 emit 函数
// 发送数据的函数
function handleEmitMsg () {
    
    
  socketio.socket.emit('message', 'data', response => {
    
    
    // 逻辑代码
  })
}
  • ここまでで Socket.IO の確立プロセスは完全に完了しました. 理解のポイントは、ソケットがイベントに基づく双方向通信のプロセスであることを理解することです. 両端はアクティブなメッセージを送信し、パッシブなメッセージを受信できます.メッセージ名は、メッセージの送信者としてこのメ​​ッセージを送信するために発行する必要があり、メッセージの受信者としてこのメ​​ッセージを受信するためには on を使用する必要があります。

おすすめ

転載: blog.csdn.net/Forever_wj/article/details/130118917