1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mojolicious::複数人でのビデオ通話

Posted at

はじめに

WebRTCを利用した複数人でのビデオ通話サンプル(Mesh)」をMojolicious::Liteに移植しました。

環境

TLSサポートにはIO::Socket::SSLが要求されます。
IO::Socket::SSLはNet::SSLeayに依存しています。
Net::SSLeayのインストールには

  • DebianとUbuntuでは、libssl-devとzlib1g-dev
  • Red Hat Enterprise LinuxとFedoraでは、openssl-develとzlib-devel

が必要になります。

インストール

webrtc_mesh_server.pl
public
  + mesh.html
  + webrtc_mesh.js

Ubuntu

sudo apt install libssl-dev
sudo apt install zlib1g-dev

CentOS(CentOS6.4上でMojolicious+WebSocket+SSL環境構築

sudo yum install openssl-devel
sudo yum install zlib-devel

IO::Socket::SSLとMojoliciousをインストールします。

cpanm IO::Socket::SSL
cpanm Mojolicious

開発サーバーを起動します。

morbo -l https://*:8443 webrtc_mesh_server.pl

サーバー

webrtc_mesh_server.jsの移植はリアルタイムチャット (Mojolicious::Lite)を参考にしました。
サーバーから3分ごと、クライアントから30秒ごと接続確認をしていましたが、3時間に延命してますのでお兄さん許して。

webrtc_mesh_server.pl
use strict;
use warnings;

use Mojo::JSON 'encode_json';
use Mojolicious::Lite;

# 接続リスト
my @connections = ();

# WebSocket処理
websocket '/' => sub {
  my $self = shift;

  $self->inactivity_timeout(10800);

  my $log = $self->log;

  # Receive message
  $self->on('json' => sub {
    my ($self, $json) = @_;
    if ($json->{join}) {
      $log->info($self->{tx}->remote_address
          . ': join room='
          . $json->{join}{room} . ', id='
          . $json->{join}{id});

      # 同一IDが存在するときは古い方を削除
      @connections = grep {
        !($_->{room} eq $json->{join}{room} && $_->{id} eq $json->{join}{id})
      } @connections;

      # 接続情報を保存
      push(@connections,
        {room => $json->{join}{room}, id => $json->{join}{id}, ws => $self});
      foreach my $data (@connections) {
        if ( $data->{room} eq $json->{join}{room}
          && $data->{id} ne $json->{join}{id})
        {
          # 新規参加者を通知
          $data->{ws}->send(encode_json({join => $json->{join}{id}}));
        }
      }
      return;
    }

    # Peerを検索
    foreach my $data (@connections) {
      if ( $data->{room} eq $json->{room}
        && $data->{id} eq $json->{dest})
      {
        # メッセージの転送
        $data->{ws}->send(encode_json($json));
        last;
      }
    }
  });
  
  # Finish
  $self->on('finish' => sub {
    @connections = grep {
      if ($_->{ws} != $self) { 1; }
      else {
        $log->info($self->{tx}->remote_address
            . ': part room='
            . $_->{room} . ', id='
            . $_->{id});
        foreach my $roomData (@connections) {
          if ( $_->{room} eq $roomData->{room}
            && $_->{id} ne $roomData->{id})
          {
            # 退出を通知
            $roomData->{ws}->send(encode_json({part => 1, src => $_->{id}}));
          }
        }
      }
    } @connections;
  });
};

app->start;

クライアント

mesh.htmlとwebrtc_mesh.jsは省略します。
(pc._remoteVideoはstartPeerConnectionだけで参照され、pcのプロパティに追加する必要はないので、ローカル変数として宣言してもよいのでは?と思います)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?