WP7应用开发笔记(6) 服务器设计

TCP服务器

服务器类图

这里模仿了WebFrom的IHttpHandler,我设计了一个ITcpHandler提供给ServiceListener让外部解析。实现类是KeyMethodHandler。

报文TcpContext包含了TcpRequest和TcpResponse,TcpRequest和消息报文结构相同,增加了从Socket获取的TcpEndpoint,TcpResponse仅仅只是回调状态和消息(暂时没有使用)。

ServiceListener、BufferManager、SocketAsyncEventArgsPool和MDSN上标准的例子接近,原则上都是为了重用Buffer和SocketAsyncEventArgs对象,节约内存开销。

 

回顾一下SocketAsyncEventArgs方式的Socket代码写法

var e = new SocketAsyncEventArgs();
e.Completed += this.OnAccept;
e.AcceptSocket = null;

...
private void ProcessAccept(SocketAsyncEventArgs e){
...
bool willRaiseEvent = this.listener.AcceptAsync(e);
if (!willRaiseEvent)
{
this.OnAccept(null, e);
}
}



...

private void OnAccept(object sender, SocketAsyncEventArgs e)
{

try
{
if (e.SocketError != SocketError.Success)
{
...
return;
}
Socket client = e.AcceptSocket;
if (client == null)
{
...
return;
}
var asyncEventArg = eventPool.Pop();
if (asyncEventArg == null)
{
...
return;
}
var token = (AsyncUserToken)asyncEventArg.UserToken;
token.Socket = client;
token.EndPoint = (IPEndPoint)client.RemoteEndPoint;
bool willRaiseEvent = client.ReceiveAsync(asyncEventArg);
if (!willRaiseEvent)
{
this.ProcessReceive(asyncEventArg);
}
}
catch (Exception err)
{
Debug.Print("Accept exception,{0}", err);
}
finally
{
e.AcceptSocket = null;
this.ProcessAccept(e);
}
}

 

命令解析

命令解析的类图

KeyMethodHandler包含了2个ICommand接口,分别的实现是KeyboardCommand用于触发直接按键事件,另外一个是MediaCommand 用于触发媒体按键。这2个类都包含了IKeyboardHook接口,实现是KeyboardHook用于调用系统接口。

媒体按键一般都组合快捷键,而且可以配置,配置类就是MediaMethodConfig.

 

调用系统接口触发键盘的实现:

public interface IKeyBoardHook
    {
        void PressKey(Keys keyCode);
        void PressKey(Keys[] keyCode);
    }

    public sealed class KeyBoardHook : IKeyBoardHook
    {
        private static readonly KeyBoardHook instance = new KeyBoardHook();

        public static KeyBoardHook Instance
        {
            get { return instance; }
        }

        private KeyBoardHook()
        {
            
        }

        private enum KeyBoard
        {
            KeyDown = 0x0001,
            KeyUp = 0x0002
        }

        public void PressKey(Keys keyCode)
        {
            PressKey(new[] { keyCode });
        }

        public void PressKey(Keys[] keyCodes)
        {
            if (keyCodes == null || keyCodes.Length == 0) return;

            int length = keyCodes.Length;
            for (int i = 0; i < length; i++)
            {
                PutDownKey(keyCodes[i]);
            }
            Thread.SpinWait(5000);
            for (int i = length - 1; i >= 0; i--)
            {
                ReceiveKey(keyCodes[i]);
            }
        }

        private static void PutDownKey(Keys keyCode)
        {
            KeyboardEvent((byte)keyCode, 0, KeyBoard.KeyDown, 0);
        }

        private static void ReceiveKey(Keys keyCode)
        {
            KeyboardEvent((byte)keyCode, 0, KeyBoard.KeyUp, 0);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "keybd_event")]
        private static extern void KeyboardEvent(
            byte bVk,
            byte bScan,
            KeyBoard dwFlags,
            int dwExtraInfo
            );
    }
posted @ 2012-01-25 16:12  kiminozo  阅读(1235)  评论(2编辑  收藏  举报