WebCFace 2.5.2
Web-based Communication Framework & Dashboard-like UI
Loading...
Searching...
No Matches
4-2. Member

See also

WebCFaceではサーバーに接続されたそれぞれのクライアントを Member と呼びます。 (たぶんROSでいうと Node に相当します)

データを受信する時など、Memberを指すために使用するのがMemberクラスです。 Client::member() で取得できます。 (C言語のAPIを除く)

  • C++ fooという名前のMember (=Clientのコンストラクタにfooを入力したクライアント) にアクセスするには、

    webcface::Member member_foo = wcli.member("foo");
    Memberを指すクラス
    Definition member.h:22
    Member member() const
    Memberを返す
    Definition field.cc:21
    Note
    • member() の引数に自身の名前を入れると、Clientオブジェクトに直接アクセスする場合と同様そのクライアント自身を指します。
      • 1.7 引数に空文字列を入れても同様です。
  • JavaScript fooという名前のMember (=Clientのコンストラクタにfooを入力したクライアント) にアクセスするには、

    import { Member } from "webcface";
    const memberFoo: Member = wcli.member("foo");
    Note
    • member() の引数に自身の名前を入れると、Clientオブジェクトに直接アクセスする場合と同様そのクライアント自身を指します。
      • 1.7 引数に空文字列を入れても同様です。
  • Python fooという名前のMember (=Clientのコンストラクタにfooを入力したクライアント) にアクセスするには、
    member_foo = wcli.member("foo");

Memberクラスから実際にそれぞれのデータにアクセスする方法は次ページ以降で説明します。

このクライアント自身もMemberの1つですが、Client自体がMemberを継承したクラスになっているので、直接Clientのオブジェクト(wcli)に対して操作すればよいです。

members

現在サーバーに接続されているメンバーのリストが得られます (無名のものと、自分自身を除く)

  • C++ Client::members() で取得できます。

    for(const webcface::Member &m: wcli.members()){
    // ...
    }
  • C
    Since
    2.0
    wcfMemberList, wcfMemberListW にchar*の配列とサイズを渡すと、メンバーの一覧を取得できます。
    const char *member_list[10];
    int actual_member_num;
    wcfMemberList(wcli, member_list, 10, &actual_member_num);
    // member_list[0] から member_list[actual_member_num - 1] (10以上だった場合はmember_list[9]まで) にメンバー名の文字列が入っている
    wcfStatus wcfMemberList(wcfClient *wcli, const char **list, int size, int *members_num)
    サーバーに接続されている他のmemberのリストを得る。
    Definition client.cc:201
    それぞれのメンバー名の文字列は、 wcfClose() するまではfreeされません。
  • JavaScript Client.members() で取得できます。

    for(const m of wcli.members()){
    // ...
    }
  • Python Client.members() で取得できます

    for m in wcli.members():
    # ...

Field系クラスの扱いについて

Memberクラスおよびこれ以降説明する各種データ型のクラス (いずれも webcface::Field を継承している) について、

  • それぞれコンストラクタが用意されていますが、正しくClientクラスから生成したオブジェクトでないと内部のデータにアクセスしようとするときに std::runtime_error (pythonでは RuntimeError) を投げます。
  • 構築元のClientの寿命が切れた後に操作しようとすると同様にstd::runtime_errorを投げます。
  • オブジェクトのコピー、ムーブは可能です。

Event

新しいメンバーが接続されたときに呼び出されるコールバックを設定できます

このクライアントが接続する前から存在したメンバーについては start(), waitConnection() 時に一度に送られるので、 コールバックの設定はstart()より前に行うと良いです。

  • C++ 2.0 引数にMemberを受け取る関数オブジェクトを Client::onMemberEntry() に設定することができます。 新しく接続したMemberの情報が引数に渡されます。

    wcli.onMemberEntry([](webcface::Member m){/* ... */});
    • 2.0 Client::waitConnection() を使う場合、 クライアントはサーバーに接続し、発見したすべてのメンバーについてonMemberEntryコールバックを呼んでからreturnします。
    Note
    2.0 onMemberEntryに限らず、webcfaceが受け取る関数オブジェクトは基本的にコピーではなくムーブされます。
  • C

    Since
    2.0

    wcfMemberEntryEvent, wcfMemberEntryEventW で引数に const char * と void * をとる関数ポインタをコールバックとして設定できます。
    新しく接続したMemberの名前が引数に渡されます。 void*引数には登録時に任意のデータのポインタを渡すことができます。(使用しない場合はNULLでよいです。)

    void callback_member_entry(const char *name, void *user_data_p) {
    struct UserData *user_data = (struct UserData *)user_data_p;
    // ...
    }
    struct UserData user_data = {...};
    wcfMemberEntryEvent(wcli, callback_member_entry, &user_data);
    wcfStatus wcfMemberEntryEvent(wcfClient *wcli, wcfEventCallback1 callback, void *user_data)
    Memberが追加された時のイベント
    Definition client.cc:209

    wcfWaitConnection() を使う場合、 クライアントはサーバーに接続し、発見したすべてのメンバーについてMemberEntryEventのコールバックを呼んでからreturnします。

  • JavaScript 引数にMemberを受け取る関数を Client.onMemberEntry() に設定することができます。 新しく接続したMemberの情報が引数に渡されます。

    import { Member } from "webcface";
    wcli.onMemberEntry.on((m: Member) => { /* ... */ });

    イベントの管理には eventemitter3 ライブラリを使用しており、 Client.onMemberEntry プロパティが返す EventTarget クラスのオブジェクトがEventEmitterのラッパーになっています。

    on(関数) または addListener(関数) でコールバックを設定し、 off(関数) または removeListener(関数) で解除したりできます。 また once(関数) で1回だけ実行されるコールバックを設定できます。

  • Python 引数にMemberを受け取る関数を Client.on_member_entry() に設定することができます。 新しく接続したMemberの情報が引数に渡されます。

    2.0

    def member_entry(m: webcface.Member):
    pass
    wcli.on_member_entry(member_entry)

    デコレータとして使うこともできます。

    @wcli.on_member_entry
    def member_entry(m: webcface.Member):
    pass

    2.0 Client.wait_connection() を使う場合、 クライアントはサーバーに接続し、発見したすべてのメンバーについてon_member_entryコールバックを呼んでからreturnします。

C++ 〜ver1.11の仕様

wcli.onMemberEntry().appendListener([](webcface::Member m){/* ... */});

C++では EventTarget クラスのオブジェクトを返します。 内部ではイベントの管理に eventpp ライブラリを使用しており、EventTargetは eventpp::CallbackList のラッパーとなっています。

appendListener(), prependListener() でコールバックを追加できます。 またinsertListener()でこれまでに追加されたコールバックのリストの途中にコールバックを挿入したり、 removeListener() でコールバックを削除したりできます。

1.7 appendListener, prependListener ではコールバックの引数が不要な場合は引数のない関数も渡すことができます。

1.11 wcli.onMemberEntry().callbackList()eventpp::CallbackListのインスタンスが得られ、 CounterRemover, ConditionalRemover などeventppに用意されているさまざまなユーティリティ機能を使用できます。 より詳細な使い方はeventppのドキュメントを参照してください。 (この場合コールバックの引数は省略できません)

wcli.onMemberEntry().callbackList().append([](webcface::Member m){/* ... */});
// CounterRemoverを使って1回呼び出されたらコールバックを削除する:
eventpp::counterRemover(wcli.onMemberEntry().callbackList())
.append([](webcface::Member m){/* ... */}, 1);
Note
ver1.10以前は eventpp::EventDispatcher を使用していたため、 EventTargetでの関数名(appendListenerなど)はCallbackListではなくEventDispatcherのものに従っている

これ以降の章でもいくつかイベントが登場しますが、いずれもこれと同様の実装、使い方になっています。

Python 〜ver1.1の仕様

def member_entry(m: webcface.Member):
pass
wcli.on_member_entry.connect(member_entry)

Pythonでは client.on_member_entry プロパティが blinker ライブラリの signal を返します。
connect(関数) でコールバックを設定できます。

クライアントの情報

以下のようなクライアントの情報を取得できます。 (WebUI の Connection Info に表示されているのと同じ情報が取得できます)

  • libVersion でWebCFaceライブラリのバージョンを取得できます。
  • libName で使用しているWebCFaceライブラリを判別できます。 C++のライブラリは "cpp", Pythonのライブラリ(webcface-python)は"python", JavaScriptのライブラリ(webcface-js)は"js"を返します。
  • remoteAddr はサーバーから見た各メンバーのIPアドレスです。
    • 1.11 Unixドメインソケットで接続している場合空文字列が返ります。
  • C++ member.libVersion(), member.libName(), member.remoteAddr() で取得できます。
  • C
    Since
    2.0
    wcfMemberLibVersion(wcli, name), wcfMemberLibName(wcli, name), wcfMemberRemoteAddr(wcli, name) で取得できます。
  • JavaScript member.libVersion, member.libName, member.remoteAddr で取得できます。
  • Python member.lib_version, member.lib_name, member.remote_addr で取得できます。

ping

クライアントの通信速度を取得できます。(単位はms) ここでは通信速度とはサーバーとクライアントの間で1往復データを送受信するのにかかる遅延です。

通信速度の情報は5秒に1回更新され、更新されたときにonPingイベントが発生します

  • C++ Member::pingStatus() でmemberの通信速度(int型)を取得できます。 デフォルトの状態ではpingの情報は受信しておらずstd::nulloptを返しますが、 pingStatusに1回アクセスすることでpingの情報がリクエストされ、それ以降は値が送られてくるようになります。

    また、 Member::onPing() でpingの情報が更新された時に実行するコールバックを設定できます。 onPing()を使うことでもリクエストが送られます。

    2.0

    wcli.member("foo").onPing([](webcface::Member m){
    std::cout << m.name() << ": " << m.pingStatus() << " ms" << std::endl;
    });
    const std::string & name() const
    Member名
    Definition member.h:36
    std::optional< int > pingStatus() const
    通信速度を調べる
    Definition member.cc:126
    • ver1.11以前では onPing().appendListener(...)
    • 1.7 appendListener, prependListener では コールバックの引数が不要な場合は引数のない関数も渡すことができます。
    • 1.11 onMemberEntry() と同様、 callbackList() でCallbackListにアクセスできます。
    • 2.0 自分自身のping値も取得できるようになりました。(wcli.pingStatus(), wcli.onPing(...))
  • C

    Since
    2.0

    wcfMemberPingStatus, wcfMemberPingStatusW でmemberの通信速度を取得できます。

    int ping_status;
    wcfMemberPingStatus(wcli, name, &ping_status);
    wcfStatus wcfMemberPingStatus(wcfClient *wcli, const char *member, int *value)
    memberの通信速度を取得
    Definition member.cc:241

    また、 wcfMemberPingEvent, wcfMemberPingEventW で引数に const char * と void * をとる関数ポインタをコールバックとして設定できます。 void*引数には登録時に任意のデータのポインタを渡すことができます。(使用しない場合はNULLでよいです。)

    void callback_ping(const char *name, void *user_data_p) {
    struct UserData *user_data = (struct UserData *)user_data_p;
    // ...
    }
    struct UserData user_data = {...};
    wcfMemberPingEvent(wcli, callback_ping, &user_data);
    wcfStatus wcfMemberPingEvent(wcfClient *wcli, const char *member, wcfEventCallback1 callback, void *user_data)
    Memberの通信速度が更新された時のイベント
    Definition member.cc:248
  • JavaScript Member.pingStatus でmemberの通信速度を取得できます。 デフォルトの状態ではpingの情報は受信しておらずnullを返しますが、 pingStatusに1回アクセスすることでpingの情報がリクエストされ、それ以降は値が送られてくるようになります。

    また、 Member.onPing でpingの情報が更新された時に実行するコールバックを設定できます。 onPingを使うことでもリクエストが送られます。

    import { Member } from "webcface";
    wcli.member("foo").onPing.on((m: Member) => {
    console.log(`${m.name}: ${m.pingStatus} ms`);
    });
    • 1.7 自分自身のping値も取得できるようになりました。(wcli.pingStatus, wcli.onPing)
    • 1.8 Member.requestPingStatus() で明示的にリクエストを送ることもできます。
  • Python Member.ping_status でmemberの通信速度(int型)を取得できます。 デフォルトの状態ではpingの情報は受信しておらずNoneを返しますが、 ping_statusに1回アクセスすることでpingの情報がリクエストされ、それ以降は値が送られてくるようになります。

    また、 Member.on_ping() でpingの情報が更新された時に実行するコールバックを設定できます。 on_ping()を使うことでもリクエストが送られます。

    2.0

    def ping_update(m: webcface.Member):
    print(f"{m.name}: {m.ping_status} ms")
    wcli.member("foo").on_ping(ping_update)
    • ver1.1以前は on_ping.connect(...)
    • 2.0 on_member_entryと同様、デコレータとして使うこともできます。
    • 2.0 自分自身のping値も取得できるようになりました。(wcli.ping_status, wcli.on_ping(...))
    • 2.0 Member.request_ping_status() で明示的にリクエストを送ることもできます。
Warning
2.0 各クライアントがPingに応答する処理はClient::sync()の中で行われるため、 sync() を呼ぶ頻度が遅いとPingの応答も遅くなり通信速度の表示に影響します。 (例えば100msに1回 sync() を呼ぶ場合通信遅延が100msあるように見える可能性があります) 4-1. Clientの送受信の章にあるようにloopSync()などを使っている場合は問題ありません。
Previous Next
4-1. Client 5-1. Value