Glue4Net簡單部署基於win服務的Socket程式

smark發表於2014-01-20

在寫一些服務應用的時候經常把要它部署到windows service中,主要是讓系統自動載入相關程式用於後臺執行.正常寫windows server需要單獨寫個程式包裝和相應的安裝類才能完成這些工作.但通過Glue4Net就可以非常簡單地把程式碼或DLL部署到windows server中執行.下面地介紹通過Glue4Net簡單地部署一個Socket程式.

安裝Glue4net

首要工作是要把Glue4net安裝下windows service中,下載http://www.ikende.com/files/file/Glue4net.rar 解壓後執行install.bat 這樣Glue4net就安裝到windows server中.這個時候你要在服務中啟動Glue4net,之後windows啟動就會自動載入.

實現一個Socket Tcp服務功能

Glue4net可以掛DLL和程式碼檔案,如果功能比較簡單那直接寫個.cs或.vb檔案即可,下面就通過c#寫一個簡單的Socket Tcp服務.

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Net;
  5 using System.Net.Sockets;
  6 using System.Text;
  7 
  8 namespace Glue4Net.SocketServer
  9 {
 10     public class Server:Glue4Net.IAppModule
 11     {
 12         private Socket mListenSocket;
 13 
 14         private IList<Socket> mClients = new List<Socket>();
 15 
 16         private bool IsAccepting = false;
 17 
 18         private void BeginReceive(Socket e)
 19         {
 20             SocketAsyncEventArgs saea = new SocketAsyncEventArgs();
 21             saea.Completed += OnReceiveCompleted;
 22             saea.SetBuffer(new byte[1024], 0, 1024);
 23             saea.UserToken = e;
 24             if (!e.ReceiveAsync(saea))
 25             {
 26                 OnReceiveCompleted(this, saea);
 27             }
 28         }
 29 
 30         private void SendData(Socket e, byte[] data, int offset, int count)
 31         {
 32             e.Send(data, offset, count, SocketFlags.None);
 33         }
 34 
 35         private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
 36         {
 37             if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
 38             {
 39                 SendData((Socket)e.UserToken, e.Buffer, 0, e.BytesTransferred);
 40                 BeginReceive((Socket)e.UserToken);
 41             }
 42             else
 43             {
 44                 mClients.Remove((Socket)e.UserToken);
 45                 Log.Error("{0} disposed!", e.RemoteEndPoint);
 46             }
 47             
 48         }
 49 
 50         private void OnAccept(object state)
 51         {
 52             while (IsAccepting)
 53             {
 54                 try
 55                 {
 56                     Socket socket = mListenSocket.Accept();
 57                     Log.Info("{0} connected!", socket.RemoteEndPoint);
 58                     mClients.Add(socket);
 59                     BeginReceive(socket);
 60                 }
 61                 catch (Exception e_)
 62                 {
 63                     Log.Info("Socket Server Accept error {0}",e_.Message);
 64                 }
 65             }
 66         }
 67 
 68         public void Load()
 69         {
 70             try
 71             {
 72                 mListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 73                 mListenSocket.Bind(new IPEndPoint(IPAddress.Any, 10024));
 74                 mListenSocket.Listen(10);
 75                 IsAccepting = true;
 76                 System.Threading.ThreadPool.QueueUserWorkItem(OnAccept);
 77                 Log.Info("Socket Server Listen @{0}", 10024);
 78                 Log.Info("Load Socket Server Success!");
 79             }
 80             catch (Exception e_)
 81             {
 82                 Log.Error("Load Socket Server Error {0}", e_.Message);
 83             }
 84         }
 85 
 86         public IEventLog Log
 87         {
 88             get;
 89             set;
 90         }
 91 
 92         public string Name
 93         {
 94             get { return "Socket Server"; }
 95         }
 96 
 97         private void DisposedSocket(Socket e)
 98         {
 99             try
100             {
101                 
102                 if (e != null)
103                 {
104                     mListenSocket.Close();
105                     mListenSocket.Shutdown(SocketShutdown.Both);
106                 }
107             }
108             catch
109             {
110             }
111         }
112 
113         public void UnLoad()
114         {
115             try
116             {
117                 IsAccepting = false;
118                 DisposedSocket(mListenSocket);
119                 foreach (Socket client in mClients)
120                 {
121                     DisposedSocket(client);
122                 }
123                 Log.Info("Unload Socket Server Success!");
124             }
125             catch (Exception e_)
126             {
127                 Log.Error("Unload Socket Server Error {0}", e_.Message);
128             }
129         }
130     }
131 }

繼承Glue4Net.IAppModule是容器載入執行的規則,需要在Load方法中實現啟動執行的工作,然後在UnLoad方法裡實現服務關閉的工作.功能完成後把程式碼儲存到任何目錄下,這裡是儲存到H:\SocketServer;以上是一個非常簡單的Socket TCP服務,把接收的資訊迴應給傳送端.

部署Socket程式

為了保證Glue4Net能載入,必須保讓程式碼目錄下存在Glue4Net.Dll這個檔案,因為它是模組載入的入口點.把程式載入到Glue4Net是非常簡單的事情,只需要在domains.config中新增一個配置即可.

1 <add name="socketserver"
2         compiler="true"
3         path="H:\SocketServer\"
4             updateWatch="true"
5                watchFilter="*.cs|*.config"/>

新增一個socketserver的應用名,然後目錄指向之前存放程式碼的目錄,確認配置資訊無誤後儲存.當檔案保後無須對Glue4Net進行重啟服務即可載入完成.針對以上編寫的程式碼部署完成後,你只需要telent 127.0.0.1 10024 即可連線到相應的服務中.

總結

通過Glue4Net非常簡單就能把程式新增到windows service中執行,而這個部署是基於熱載入.當新增或修改某些應用的時候,是完全不會影響其他應用的正常工作.

相關文章