Microsoft.AspNet.SignalR.Client for Portable Class Library

第二弾。

タイトルの通り、SignalRの.NETクライアントライブラリのPortableバージョンです。
NuGetで公開しているので、すぐに使えます。「Microsoft.AspNet.SignalR.Client.Portable」で探してください。
(CodePlex: Microsoft.AspNet.SignalR.Client for Portable Class Library

例によってVS2012でビルドしました。Xbox360は外れますが、Windows Phone 7.5はOKです。現在オフィシャルで配布しているNuGetのClientライブラリはWindows Phone 7.5が駄目なので、そっち方面の人にどうぞ。
インターフェイスに変更はありません。

こんなコードをクライアントに書いて(例はWP7.5):

// Page class (XAML code behind)
public partial class MainPage : PhoneApplicationPage
{
	private HubConnection client_;
	private IHubProxy sampleHub_;

	// Constructor
	public MainPage()
	{
		InitializeComponent();
	}

	// Page loaded
	private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
	{
		if (client_ == null)
		{
			client_ = new HubConnection("http://localhost:27224/");
			sampleHub_ = client_.CreateHubProxy("SampleHub");

			sampleHub_.On(
				"Receive",
				new Action<string>(
					x => this.Dispatcher.BeginInvoke(
						new Action(() => listBox.Items.Add(x.ToString())))));

			client_.Start();
		}
	}

	// Button clicked
	private void sendButton_Click(object sender, System.Windows.RoutedEventArgs e)
	{
		var r = new Random();
		var message = string.Format("Random={0}", r.Next());
		sampleHub_.Invoke("Send", message);
	}
}

サーバー側に:

// OWIN Startup entry point definition
[assembly: OwinStartup(typeof(MyWebApplication.Startup))]

namespace MyWebApplication
{
    // OWIN Startup Code
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // SignalR mapping
            app.MapSignalR();
        }
    }

    // The hub
    public class SampleHub : Hub
    {
        // Hub method
        public void Send(string text)
        {
            // Callback all client's "Receive" method.
            this.Clients.All.Receive(text);
        }
    }
}

Page_Loadedで初期化すべきかどうかはちょっと甘いです(WPアプリの開発経験が浅いので)。正しいと思う方法で実装して下さい。

SgmlReader for Portable Class Library

あけましておめでとうございます。本年もよろしくお願いします。

早速本題。
年始早々取り組んでいる事の依存関係の末端に「SgmlReader」があり、そのままではバージョンとか面倒な事もあって、Portable Class Library化してNuGetで公開しました。

NuGet package ID: SgmlReaderPortable
CodePlex project: SgmlReader for Portable Class Library

ええと、VS2012で作ったので、WP7とかXbox360でも行けるとか(勿論、未確認w)、誰得仕様です。
Portable化のため、外部リソースへのHTTP接続とか出来ないので、デリゲートで外部から依存注入出来るようにしています。

超簡単な例:

// Open stream
using (var stream = new FileStream("target.html", FileMode.Open, FileAccess.Read, FileShare.Read))
{
	var tr = new StreamReader(stream, Encoding.UTF8);

	// Setup SgmlReader
	var sgmlReader = new SgmlReader(tr)
		{
			DocType = "HTML",				// Use internal HTML4 DTD (No external access)
			WhitespaceHandling = true,		// Means WhitespaceHandling.All
			CaseFolding = CaseFolding.ToLower
		};

	// create document
	var document = new XmlDocument();
	document.PreserveWhitespace = true;
	document.XmlResolver = null;
	document.Load(sgmlReader);
}

外部リソースにアクセス可能にする例:

// Open stream
using (var stream = new FileStream("target.sgml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
	var tr = new StreamReader(stream, Encoding.UTF8);

	// Define base uri
	var baseUri = new Uri("http://www.example.com/");

	// Setup SgmlReader
	var sgmlReader = new SgmlReader(tr, baseUri,

		// Stream opener delegate (Separate physical resource access)
		uri => new StreamInformation
			{
				Stream = WebRequest.Create(uri).GetResponse().GetResponseStream(),
				DefaultEncoding = Encoding.UTF8
			})

		{
			WhitespaceHandling = true,
			CaseFolding = CaseFolding.ToLower
		};

	// create document
	var document = new XmlDocument();
	document.PreserveWhitespace = true;
	document.XmlResolver = null;
	document.Load(sgmlReader);
}

取りあえず、一つ依存が片付いた…