使用云服务要精打细算:如何仅花10美元来举行为期两天的虚拟会议


[原文发表地址] Penny Pinching in the Cloud: How to run a two day Virtual Conference for $10

[原文发表时间]  2013-04-26 11:59

我们刚结束DotNetConf活动的一天,它是由我们社区发起的喜爱.NET开发平台和开源的开发者免费在线会议!

更新所有来自DotNetConf的视频现在都在线,可供需要的人观看

会议平台

把运行我们的会议的软件说成运是一个平台很有趣,因为听起来很像个“企业”,很正式。过去,我们完成的aspConfmvcConf是由赞助商帮忙付费的。我们以前使用第九频道,并且有个工作室,会议流不是自西雅图就是使用Live Meeting。

然而,今年我们想要更便宜且更分散的流。我们希望演讲者来自各个时区。要多便宜呢?我们估计大概10美元吧。我之后会得到完整的账单,基本上我们想做的就是扩展,演讲,然后缩减。

视频广播和屏幕共享

  • 今年我们使用谷歌的带有"Hangouts On Air"特性的Hangouts。由一个“dotnetconf”谷歌帐号邀请参与者到一个Hang Out并在视频会议开始前选择“on air”选框。然后我们使用Hangout工具盒来动态的添加屏幕图像和演讲者标签。每个人把屏幕调成1280x768,实时流缩减到480p。
  • 一旦你点击了“开始广播”你就向实时流提供了一个YouTube链接。当你点击终止广播,视频会在几分钟内发布到你的YouTube页面上。视频会议发起人(我或javier)会点击“在广播中隐藏”然后消失。你可以在下面的屏幕截图中看到我消失了。我还在,不过只在我需要出现时才会出现。当只有一个活动的参与者时,这个软件会调到全屏,这是我们想要的。
  • 重要的注意点:相比一个8小时的Hangout,我们是每个演讲者依次发表讲话的。这意味着我们的谈话已经分散在YouTube页面上。YouTube视频可以修剪头尾,所以不至于开头太粗糙。

hangoutonair_3

数据

大惊喜!没有数据库。一个都不需要。我们用写在WebMatrix里的ASP.NET Web页面来运行一个两个页面的站点。它在Azure云里运行,不过鉴于我们的数据集(演讲者,时间表,视频流位置,等等)没什么大的改变,我们把所有数据都放到XML文件里。这就是数据,不过是个穷人的数据库。为什么要为不需要的东西付费?

讲话期间我们怎么更新“数据库”的呢?准备开开眼吧。数据是在Dropbox里。(是,可以用SkyDrive或其他的URL,但我们使用了DropBox)

我们的web应用从Dropbox URL拉取数据并缓存起来。工作的不错。

   1: <appSettings>
   2:    <add key="url.playerUrl" value="https://dl.dropboxusercontent.com/s/fancypantsguid/VideoStreams.xml" />
   3:    <add key="url.scheduleUrl" value="https://dl.dropboxusercontent.com/s/fancypantsguid/Schedule.xml" />
   4:    <add key="url.speakerUrl" value="https://dl.dropboxusercontent.com/s/fancypantsguid/Speakers.xml" />
   5:    <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[your namespace].servicebus.windows.net;SharedSecretIssuer=owner;SharedSecretValue=[your secret]" />
   6: </appSettings>

代码很简单,就像代码应该的那样简单。想显示时间表?没错,这是个表,是一个时间表。

@foreach(var session in schedule) {
var confTime = session.Time;
var pstZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var attendeeTime = TimeZoneInfo.ConvertTimeToUtc(confTime, pstZone);
<tr>
<td>
<p>@confTime.ToShortTimeString() (PDT)</p>
<p>@attendeeTime.ToShortTimeString() (GMT)</p>
</td>
<td>
<div class="speaker-info">
<h4>@session.Title</h4>


<span class="company-name"><a class="speaker-website" href="/speakers.cshtml?speaker=@session.Twitter">@session.Name</a></span>


<p>@session.Abstract</p>
</div>
</td>
</tr>
}

向外扩展clip_image003

我们已经从一个极小的Azure 网站转到两个大的(最终,两个中等大小完全是大材小用)网站。

我们只在会议期间扩展(也只在这期间付钱),等我们结束了就缩减。不需要的时候就不用花钱。

image_8

实时更新站点信号

由于YouTube链接随着每个Hangout改变,我们遇到了问题:会议参与者必须不断刷新自己来获得新的URL。对付这种情况有很多种解决方案,我想你已经想到了。我们可以元刷新,刷新计时器,但这些都还达不到要求。我们也希望在停机时间展示一些视频。在我们准备下一位演讲者时,其他人可以看视频。

昨晚10点我们认识到这是个问题。Javier和我上了Skype,并想出了这个深夜黑客。

如果每个人在看视频的时候都有SignalR呢?那我们就可以从管理控制台推送下一个YouTube视频了。

设想一下,有一个观看者(你),一个管理员(我),还有服务器(Hub)。

观看者的主页里会有这个在他们包含了/signalr/hub之后 JavaScript代码如下:

   1: $(function () {
   2:     var youtube = $.connection.youTubeHub;
   3:     $.connection.hub.logging = true;
   4:  
   5:     youtube.client.updateYouTube = function (message, password) {
   6:         $("#youtube").attr("src", "https://www.youtube.com/embed/" + message + "?autoplay=1");
   7:     };
   8:     $.connection.hub.start();
   9:  
  10:     $.connection.hub.disconnected(function () {
  11:         setTimeout(function () {
  12:             $.connection.hub.start();
  13:         }, 5000);
  14:     });
  15: });

观察者在监听,观看来自服务器的带有YouTube视频简短代码的SignalR消息。当我们获取到一个新消息时,换出iFrame。简单并且有用。

这是放置下一个YouTube视频代码的管理控制台(我使用WebMatrix ASP.NET Web页面的Razor,所以这是混合的HTML/JS代码)

 

   1: <div id="container">
   2:         <input type="text" id="videoId" name="videoId">
   3:  
   4:         <input type="text" id="password" name="passsword" placeholder="password">
   5:  
   6:         <button id="playerUpdate" name="playerUpdate">Update Player</button>
   7: </div>
   8:  
   9: @section SignalR {
  10: <script>    
  11:     $(function () {
  12:         var youtube = $.connection.youTubeHub;
  13:         $.connection.hub.logging = true;
  14:  
  15:         $.connection.hub.start().done(function () {
  16:             $('#playerUpdate').click(function () {
  17:                 youtube.server.update($('#videoId').val(), $('#password').val());
  18:             });
  19:         });
  20:         $.connection.hub.disconnected(function() {
  21:           setTimeout(function() {
  22:               $.connection.hub.start();  
  23:         }, 5000);
  24: });
  25:     });
  26: </script>
  27: }

我们放入了简短的代码,密码和更新。所有这些一定很复杂吧?强大的SignalR后端运行在云上,依靠强大的Azure和服务总线?那些代码贴在一个简单的博客里一定很复杂,是吗?看下面,朋友:

   1: public class YouTubeHub : Microsoft.AspNet.SignalR.Hub
   2: {
   3:     public void update(string message, string password)
   4:     {
   5:         if (password.ToLowerInvariant() == "itisasecret")
   6:         {
   7:             Clients.All.updateYouTube(message);
   8:             ConfContext.SetPlayerUrl(message);
   9:         }
  10:     }
  11: }

这要么是语言纯粹论者的噩梦或是实用主义者的梦。不管怎样,我们已经运行了一整天了,而且很有用。谈话间隙我们放入预先录制的谈话和信息,当开始实时谈话的时候我们一样的推送。

我们也会随着当前的视频流更新DropBox链接,这样新来的人也能看到最新的视频,以防来的人因视频推送消息已经过去而无法连上。

image_11

扩展性怎么样?我们有时有两台机器,所以我们需要SignalR“推送更新的youtube视频消息”能跨越扩展底板。这还要花费10分钟。

使用Azure务总线扩展SignalR

我们使用Signal 1.1 Beta 加上 Azure服务总线来做扩展并添加了一个Azure服务总线到我们的帐号。我们的应用启动改变了,添加这些来调用UseServiceBus():

   1: string poo = "Endpoint=sb://dotnetconf-live-bus.servicebus.windows.net/;SharedSecretIssuer=owner;SharedSecretValue=g57totalsecrets=";   
   2: GlobalHost.DependencyResolver.UseServiceBus(poo,"dotnetconf");
   3: RouteTable.Routes.MapHubs();

现在Signal使用服务总线话题来在两个web服务器中间来传递通知。我可以从web 1推送一个新视频,通过Signal的实时持久连接把它发送给web 1和web 2(或者web n)上的每一个人。

image_14

我们一完成就会删除这个服务总线话题。我讨厌账单超过五分钱。这是Azure站点的花费示例:

432,000 Service Bus messages cost 432,000/10,000 * $0.01 = 44 * $0.01 = $0.44 per day.

我不太清楚我们完成了多少条消息,不过我可以确定花不了几个钱,放心了。

谢社区!

· 非常感谢Jin yang设计了dotnetConf的logo。推特一下@jzy,告诉他你认为他很专业。感谢 Dave Ward把Jzy的设计转换成HTML!

· 荣耀和感谢归于Javier Lozano,感谢他的编码,他的组织,他的头脑风暴和他的辛苦工作。昨晚他和我在一起用了几个小时来攻击SignalR和DotNetConf.net站点,这也是很酷的。

· 感谢David Fowler,他说“只要花10分钟来添加服务总线”

· 感谢Eric HexterJon Galloway的组织能力和处理会议事件时间上的天赋!

· 最重要的,要感谢那些贡献时间的演讲者社区里观看的,交流的,和我们一起玩的朋友们!

赞助商Windows Azure开发者挑战来了。完成5个编程挑战就有机会获得spot奖,Stage奖和Grand奖。总计超过16000美元,65个机会赢取!


Comments (0)

Skip to main content