#前置き
とあるプロジェクトにて
Windows(おそらくC# WPF)でOSC通信をしそうな匂いがしてきまして
ofとかiOSとかではやったことあったのですが、Windows系では今までやったことなかったので
やりかたを調べてみたのでメモ的に書いておきます。
#使わせていただくライブラリ
以下のように、NuGetで「OSC」を検索したら
最初に出てきた「Rug.Osc」を使わせていただくことにします。
MITライセンスですし。大変ありがたいことです!
実際にまだ使ってないのでいい感じかどうかは検証できてません。
#OSC送信側ソース
送信はこんな感じでかいてみました。(ボタンクリック時にOSC送信)
IPアドレスとかポートはとりあえず決め打ちですが・・・
private void Button_Click(object sender, RoutedEventArgs e)
{
// 送信先のIPアドレスを設定
IPAddress sendAddress = IPAddress.Parse("192.168.0.14");
// OSCのセンダーをポート12345で作る usingなので破棄はしてくれる
using (OscSender oscSender = new OscSender(sendAddress, 12345))
{
// 接続
oscSender.Connect();
// OSC送信
oscSender.Send(new OscMessage("/testmsg", 1, 2));
}
}
#OSC受信側ソース
受信はこんな感じでかいてみました。
(起動時にレシーバーを準備してTaskで受信待ちを繰り返し処理)
public partial class MainWindow : Window
{
// OSCのレシーバー
private OscReceiver m_OscReceiver;
// OSC受信待ちをするタスク
private Task m_OscReceiveTask = null;
public MainWindow()
{
InitializeComponent();
// OSCのレシーバーをポート1234で作る
m_OscReceiver = new OscReceiver(12345);
// OSCのレシーバーを接続
m_OscReceiver.Connect();
// OSC受信用のタスクを生成
m_OscReceiveTask = new Task(() => OscListenProcess());
// タスクをスタート
m_OscReceiveTask.Start();
}
/// <summary>
/// OSC受信をListenする処理
/// Taskで実行されており、繰り返し受信を確認し
/// 接続が終了したら処理を終わらせる
/// </summary>
private void OscListenProcess()
{
try
{
// OSCレシーバーが終了されるまで繰り返し処理する
while (m_OscReceiver.State != OscSocketState.Closed)
{
// 受信待ち(メッセージを受信したら処理が帰ってくる)
OscPacket packet = m_OscReceiver.Receive();
// 受信したメッセージをコンソールに出力
Console.WriteLine(packet.ToString());
}
}
catch (Exception ex)
{
// 例外処理 発生時はコンソールに出力
// ただし
// m_OscReceiver.Receive()で受信待ち状態の時に終了処理(m_OscReceiver.close())をすると
// 正しい処理でもExceptionnとなるため、接続中かで正しい処理か例外かを判断する
if (m_OscReceiver.State == OscSocketState.Connected)
{
Console.WriteLine(ex.Message);
}
}
}
private void Window_Closed(object sender, EventArgs e)
{
m_OscReceiver.Close();
}
}
コメントにも書きましたが、レシーバーをクローズ処理すると受信待ちで例外が発生するのですが
Exceptionで区別がつかなかったので、レシーバーが接続中かで判断しています。
これが正しいか分からなかったですが、サンプルもそうなってたのでよしとしました。
#感想
・思ったよりも簡単でした、ライブラリを作ってくれた方に感謝です!
・実際に使ってないので問題ないかとかはテストしないと分からないからやらないといけないですね。
・中身を見させていただいたらSystem.Net.Socketsをつかってました。(当たり前なのですが)