4 Commits

Author SHA1 Message Date
sta
fc6ee2db12 Merged enix's fix (THX enix) and made a little change (because close method dose not work). 2011-06-05 17:39:43 +09:00
sta
ab1f09283b fix Ext.cs, WebSocket.cs 2010-11-09 22:06:20 +09:00
sta
240a4e61ba fix Ext.cs, WebSocket.cs and Add wsclient1/* 2010-11-01 21:36:33 +09:00
sta
7cea727db1 fix WebSocket.cs 2010-10-28 16:44:14 +09:00
42 changed files with 302 additions and 90 deletions

View File

@@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "websocket-sharp", "websocke
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsclient", "wsclient\wsclient.csproj", "{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsclient1", "wsclient1\wsclient1.csproj", "{B0B609B7-A81C-46B0-A9B8-82E9716D355B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,14 @@ Global
{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.Build.0 = Release|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release|Any CPU.Build.0 = Release|Any CPU
{B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU
{B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU
{B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

View File

@@ -2,7 +2,7 @@
<MonoDevelop.Ide.Workspace ActiveConfiguration="Release" ctype="Workspace" />
<MonoDevelop.Ide.Workbench ActiveDocument="websocket-sharp/WebSocket.cs" ctype="Workbench">
<Files>
<File FileName="websocket-sharp/WebSocket.cs" Line="261" Column="1" />
<File FileName="websocket-sharp/WebSocket.cs" Line="80" Column="19" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>

View File

@@ -34,6 +34,22 @@ namespace WebSocketSharp
{
public static class Ext
{
public static bool AreNotEqualDo(
this string expected,
string actual,
Func<string, string, string> func,
out string ret)
{
if (expected != actual)
{
ret = func(expected, actual);
return true;
}
ret = String.Empty;
return false;
}
public static bool EqualsWithSaveTo(this int asByte, char c, List<byte> dist)
{
byte b = (byte)asByte;
@@ -83,7 +99,7 @@ namespace WebSocketSharp
return new String(secKey.ToArray());
}
public static Byte[] InitializeWithPrintableASCII(this Byte[] bytes, Random rand)
public static byte[] InitializeWithPrintableASCII(this byte[] bytes, Random rand)
{
for (int i = 0; i < bytes.Length; i++)
{
@@ -93,12 +109,39 @@ namespace WebSocketSharp
return bytes;
}
public static void NotEqualsDo(this string expected, string actual, Action<string, string> act)
public static bool IsValid(this string[] response, byte[] expectedCR, byte[] actualCR, out string message)
{
if (expected != actual)
string expectedCRtoHexStr = BitConverter.ToString(expectedCR);
string actualCRtoHexStr = BitConverter.ToString(actualCR);
Func<string, Func<string, string, string>> func = s =>
{
act(expected, actual);
return (e, a) =>
{
#if DEBUG
Console.WriteLine("WS: Error @IsValid: Invalid {0} response.", s);
Console.WriteLine(" expected: {0}", e);
Console.WriteLine(" actual : {0}", a);
#endif
return String.Format("Invalid {0} response: {1}", s, a);
};
};
Func<string, string, string> func1 = func("handshake");
Func<string, string, string> func2 = func("challenge");
string msg;
if ("HTTP/1.1 101 WebSocket Protocol Handshake".AreNotEqualDo(response[0], func1, out msg) ||
"Upgrade: WebSocket".AreNotEqualDo(response[1], func1, out msg) ||
"Connection: Upgrade".AreNotEqualDo(response[2], func1, out msg) ||
expectedCRtoHexStr.AreNotEqualDo(actualCRtoHexStr, func2, out msg))
{
message = msg;
return false;
}
message = String.Empty;
return true;
}
public static void Times(this int n, Action act)

View File

@@ -53,6 +53,8 @@ namespace WebSocketSharp
get { return uri.ToString(); }
}
private Object sync = new Object();
private volatile WsState readyState;
public WsState ReadyState
{
@@ -63,17 +65,18 @@ namespace WebSocketSharp
switch (value)
{
case WsState.OPEN:
readyState = value;
if (OnOpen != null)
{
OnOpen(this, EventArgs.Empty);
}
goto default;
break;
case WsState.CLOSING:
case WsState.CLOSED:
lock(sync)
{
close(value);
break;
default:
readyState = value;
}
break;
}
}
@@ -129,8 +132,41 @@ namespace WebSocketSharp
this.protocol = protocol;
}
public WebSocket(
string url,
EventHandler onOpen,
MessageEventHandler onMessage,
MessageEventHandler onError,
EventHandler onClose)
: this(url, String.Empty, onOpen, onMessage, onError, onClose)
{
}
public WebSocket(
string url,
string protocol,
EventHandler onOpen,
MessageEventHandler onMessage,
MessageEventHandler onError,
EventHandler onClose)
: this(url, protocol)
{
this.OnOpen += onOpen;
this.OnMessage += onMessage;
this.OnError += onError;
this.OnClose += onClose;
Connect();
}
public void Connect()
{
if (readyState == WsState.OPEN)
{
Console.WriteLine("WS: Info @Connect: Connection is already established.");
return;
}
createConnection();
doHandshake();
@@ -248,39 +284,12 @@ namespace WebSocketSharp
private void doHandshake()
{
#if !CHALLENGE
string request = createOpeningHandshake();
#else
byte[] expectedRes, actualRes = new byte[16];
string request = createOpeningHandshake(out expectedRes);
#endif
byte[] expectedCR, actualCR;
string request = createOpeningHandshake(out expectedCR);
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: Handshake from client: \n{0}", request);
#endif
byte[] sendBuffer = Encoding.UTF8.GetBytes(request);
wsStream.Write(sendBuffer, 0, sendBuffer.Length);
string[] response;
List<byte> rawdata = new List<byte>();
while (true)
{
if (wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata))
{
#if CHALLENGE
wsStream.Read(actualRes, 0, actualRes.Length);
rawdata.AddRange(actualRes);
#endif
break;
}
}
response = Encoding.UTF8.GetString(rawdata.ToArray())
.Replace("\r\n", "\n").Replace("\n\n", "\n")
.Split('\n');
string[] response = sendOpeningHandshake(request, out actualCR);
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: Handshake from server:");
foreach (string s in response)
@@ -288,25 +297,15 @@ namespace WebSocketSharp
Console.WriteLine("{0}", s);
}
#endif
Action<string, string> act = (e, a) =>
string msg;
if (!(response.IsValid(expectedCR, actualCR, out msg)))
{
throw new IOException("Invalid handshake response: " + a);
};
#if !CHALLENGE
"HTTP/1.1 101 Web Socket Protocol Handshake".NotEqualsDo(response[0], act);
#else
"HTTP/1.1 101 WebSocket Protocol Handshake".NotEqualsDo(response[0], act);
#endif
"Upgrade: WebSocket".NotEqualsDo(response[1], act);
"Connection: Upgrade".NotEqualsDo(response[2], act);
throw new IOException(msg);
}
for (int i = 3; i < response.Length; i++)
{
#if !CHALLENGE
if (response[i].Contains("WebSocket-Protocol:"))
#else
if (response[i].Contains("Sec-WebSocket-Protocol:"))
#endif
{
int j = response[i].IndexOf(":");
protocol = response[i].Substring(j + 1).Trim();
@@ -315,29 +314,11 @@ namespace WebSocketSharp
}
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: Sub protocol: {0}", protocol);
#endif
#if CHALLENGE
string expectedResToHexStr = BitConverter.ToString(expectedRes);
string actualResToHexStr = BitConverter.ToString(actualRes);
expectedResToHexStr.NotEqualsDo(actualResToHexStr, (e, a) =>
{
#if DEBUG
Console.WriteLine("WS: Error @doHandshake: Invalid challenge response.");
Console.WriteLine("\texpected: {0}", e);
Console.WriteLine("\tactual : {0}", a);
#endif
throw new IOException("Invalid challenge response: " + a);
});
#endif
ReadyState = WsState.OPEN;
}
#if !CHALLENGE
private string createOpeningHandshake()
#else
private string createOpeningHandshake(out byte[] expectedRes)
#endif
private string createOpeningHandshake(out byte[] expectedCR)
{
string path = uri.PathAndQuery;
string host = uri.DnsSafeHost;
@@ -350,16 +331,9 @@ namespace WebSocketSharp
}
string subProtocol = protocol != String.Empty
#if !CHALLENGE
? String.Format("WebSocket-Protocol: {0}\r\n", protocol)
#else
? String.Format("Sec-WebSocket-Protocol: {0}\r\n", protocol)
#endif
: protocol;
#if !CHALLENGE
string secKeys = String.Empty;
string key3ToAscii = String.Empty;
#else
Random rand = new Random();
uint key1, key2;
@@ -374,8 +348,8 @@ namespace WebSocketSharp
string key3ToAscii = Encoding.ASCII.GetString(key3);
expectedRes = createExpectedRes(key1, key2, key3);
#endif
expectedCR = createExpectedCR(key1, key2, key3);
return "GET " + path + " HTTP/1.1\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
@@ -387,7 +361,7 @@ namespace WebSocketSharp
key3ToAscii;
}
private byte[] createExpectedRes(uint key1, uint key2, byte[] key3)
private byte[] createExpectedCR(uint key1, uint key2, byte[] key3)
{
byte[] key1Bytes = BitConverter.GetBytes(key1);
byte[] key2Bytes = BitConverter.GetBytes(key2);
@@ -401,6 +375,31 @@ namespace WebSocketSharp
return md5.ComputeHash(concatKeys);
}
private string[] sendOpeningHandshake(string openingHandshake, out byte[] challengeResponse)
{
challengeResponse = new byte[16];
List<byte> rawdata = new List<byte>();
byte[] sendBuffer = Encoding.UTF8.GetBytes(openingHandshake);
wsStream.Write(sendBuffer, 0, sendBuffer.Length);
while (true)
{
if (wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata))
{
wsStream.Read(challengeResponse, 0, challengeResponse.Length);
break;
}
}
return Encoding.UTF8.GetString(rawdata.ToArray())
.Replace("\r\n", "\n").Replace("\n\n", "\n")
.Split('\n');
}
private void message()
{
#if DEBUG

View File

@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG,CHALLENGE</DefineConstants>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
@@ -36,7 +36,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug_Ubuntu</OutputPath>
<DefineConstants>DEBUG,CHALLENGE</DefineConstants>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -14,11 +14,11 @@ namespace Example
//using (WebSocket ws = new WebSocket("ws://localhost:8000/"))
using (WebSocket ws = new WebSocket("ws://localhost:8000/", "chat"))
{
/*ws.OnOpen += (o, e) =>
ws.OnOpen += (o, e) =>
{
//Do something.
ws.Send("Hi, all!");
};
*/
ws.OnMessage += (o, s) =>
{
#if NOTIFY

Binary file not shown.

27
wsclient1/AssemblyInfo.cs Normal file
View File

@@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("wsclient1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

Binary file not shown.

Binary file not shown.

BIN
wsclient1/bin/Debug/wsclient1.exe Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

65
wsclient1/wsclient1.cs Normal file
View File

@@ -0,0 +1,65 @@
#if NOTIFY
using Notifications;
#endif
using System;
using System.Threading;
using WebSocketSharp;
namespace Example
{
public class Program
{
public static void Main(string[] args)
{
EventHandler onOpen = (o, e) =>
{
Console.WriteLine("[WebSocket] Opened.");
};
MessageEventHandler onMessage = (o, s) =>
{
#if NOTIFY
Notification nf = new Notification("[WebSocket] Message",
s,
"notification-message-im");
nf.AddHint("append", "allowed");
nf.Show();
#else
Console.WriteLine("[WebSocket] Message: {0}", s);
#endif
};
MessageEventHandler onError = (o, s) =>
{
Console.WriteLine("[WebSocket] Error : {0}", s);
};
EventHandler onClose = (o, e) =>
{
Console.WriteLine("[WebSocket] Closed.");
};
//using (WebSocket ws = new WebSocket("ws://localhost:8000/", onOpen, onMessage, onError, onClose))
using (WebSocket ws = new WebSocket("ws://localhost:8000/", "chat", onOpen, onMessage, onError, onClose))
{
Thread.Sleep(500);
Console.WriteLine("\nType \"exit\" to exit.\n");
string data;
while (true)
{
Thread.Sleep(500);
Console.Write("> ");
data = Console.ReadLine();
if (data == "exit")
{
break;
}
ws.Send(data);
}
}
}
}
}

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B0B609B7-A81C-46B0-A9B8-82E9716D355B}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>wsclient1</RootNamespace>
<AssemblyName>wsclient1</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug_Ubuntu|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug_Ubuntu</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
<Externalconsole>true</Externalconsole>
<DefineConstants>DEBUG,NOTIFY</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_Ubuntu|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release_Ubuntu</OutputPath>
<DefineConstants>NOTIFY</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="notify-sharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=2df29c54e245917a">
<Package>notify-sharp</Package>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="wsclient1.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\websocket-sharp\websocket-sharp.csproj">
<Project>{B357BAC7-529E-4D81-A0D2-71041B19C8DE}</Project>
<Name>websocket-sharp</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

BIN
wsclient1/wsclient1.pidb Normal file

Binary file not shown.