Rajnish Noonia

Year: 2010

  • .Net Script Editor (C#,Vb.net Mini IDE)

    Complete Visual Studio IDE (source code included) in single user contol that can be used in your windows application to provide scripting feature in languages like c# abd vb.net.IDE have features like code intellisence,reference to .Net assemblies,COM libraries & web services.The code editor supports lot coloring for languages like c,c++ c#,vb.net,sql etc..Refrectoring features like converting c# code to vb.net code in single click.

    Add scripting functionality to your application,features of MS Script control (Functions like AddObject) and some features of VSA/Visual Studio editor like intellisence, code completion etc. Mini .Net IDE in single winform control.

    The source code / article published here is to provide features of MS Script control (Functions like AddObject) and some features of VSA/Visual Studio editor like intellisence, code completion etc. The control supports C# and VB.net language however can be easily modified to support any .net language. You can use COM references, .Net references & Web References. The control supports Visual studio IDE features like bookmark, highlighting interpreter errors & compiler errors, adding multiple classes and interfaces. You can imagine visual studio IDE build in single control with feature like AddObject from MS Script Control. To use this control you just need to drag and drop it to your winforms and add few lines of code to add instance of object which you want to access in the scripts.

    Source code at :
  • Silverlight WebSockets – Duplex Communication

    A duplex communication system is a system composed of two connected parties or devices that can communicate with one another in both directions. Duplex communication is required when you need to send some data in the reverse direction i.e. from Server to client. For scenario purpose assume that something happens on server (some event is received from source) and message from server should be sent to connected clients. Off-course the solution should be highly scalable with low latency client and server.

    Let’s talk about silverlight client in our scenario

     There could be couple of options with silverlight client demonstrated by Gill Cleeren In series of article “The duplex story: looking at duplex communication in Silverlight 4”

    Silverlight 4.0 now supports 3 different types of duplex communications

    • HTTP Polling Duplex: Duplex requires that the server can itself initiate communication, which is not supported by HTTP, HTTP Polling duplex (HTTP long polling, or Comet-style) protocol allows us to do bi-directional communication over HTTP. What happens behind the scenes is the following:
      • The Silverlight client initiates the communication by sending an initial request to the service.
      • After the client is registered with the service, it continuously starts polling the service for updates.
      • Whenever the service has new messages to send to the client, they are queued up until a new poll arrives from the client.

    The HTTP Polling Duplex is therefore not real duplexing: it creates an illusion of duplex communication by polling (at network layer) so frequently that it looks as if the messages are pushed from the service to the client. If you still want to use this method here is the link for you to tune performance of http polling duplex.

    • Sockets: Socket is implemented through the use of a TcpListener, Being pure TCP endpoints, sockets are fast and true duplex communicators. However sockets in Silverlight can only work over ports between 4502 and 4534 making it unsuitable for duplex communication over the internet. Secondly you need to build policy server to provide clientaccesspolicy.xml for sockets.Note that Silverlight 4 also allows that the policy calls are made over HTTP.
    • net.tcp binding: this entirely new binding, added in Silverlight 4, also supports duplex communication. net.tcp combines advantages of both polling duplex and sockets. Its programming model is, just like polling duplex, based on WCF. That means that we can take advantage of automatic proxy generation inside Visual Studio.
    • Poll based communication: Not scalable, out of scope.

    So what’s next?

     HTML 5 – WebSockets

    Web socket protocol or WebSockets are “TCP for the Web,” a next-generation bidirectional communication technology for web applications being standardized in part of Web Applications 1.0.

    The Web Sockets API enables web applications to handle bidirectional communications with server-side process in a straightforward way. Once you get a Web Socket connection, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler. The protocol is not raw TCP because it needs to provide the browser’s “same-origin” security model. It’s also not HTTP because web socket traffic differers from HTTP’s request-response model. you do need a new server implementation to communicate with web sockets .

    web socket prototype is out now at http://html5labs.interoperabilitybridges.com/prototypes/available-for-download/websockets/html5protos_Download or websocket msi from here

     for more information see : http://tomasz.janczuk.org/2010/12/websockets-wcf-service-silverlight-and.html

    Please also find the published websocket transport binding (Incomplete project)  here which i was trying to build using custom duplex WCF channel.

  • SNMP Trap Listener

    Simple Network Management Protocol (SNMP) is an “Internet-standard protocol for managing devices on IP networks. Devices that typically support SNMP include routers, switches, Servers, workstations, printers, modem tracks etc. It is used mostly in network management systems to monitor network-attached devices for conditions that warrant administrative attention.

    SNMP exposes management data in the form of variables on the managed systems, which describe the system configuration. These variables can then be queried (and sometimes set) by managing applications.

    The code attached in this article is .net based windows service to trap SNMP messages (SNMP v2) and process them accordingly. The service is capable to handle thousands of messages per second by using .net threads. One thread listens for incoming messages and pump them in message queue while another thread will extract and process the messages from another end of the queue.

    The SNMP service in this article depends on windows “SNMP Trap Service”.

    The source code also includes project “(SNMPSendTrap)” to send test SNMP v2 traps. 

    Download source code for SNMP Listener (Vs2010)

  • Custom Domain Service Factory

    Parameterized constructors are not allowed in WCF RIA domain service, however your object model may requires to have constructor with arguments. For example EmployeeService (in this example) is WCF RIA Domain Service which requires Authentication and have constructor with authenticated User instance as parameter. The activate the service in such scenario you need to provide your own custom domain factory calls and plug the factory in Application_Start event of Global.aspx.

    Sample Employee Service class

    [EnableClientAccess()]
    [RequiresAuthentication()]
    public class EmployeeService : DomainService
    {
            
        public EmployeeService(User user)
        {
                
        }
        //......
            
    }

    Custom Domain service factory

    internal sealed class DomainServiceFactory : IDomainServiceFactory
    {
        private IDomainServiceFactory _defaultFactory;
    
    
        public DomainServiceFactory(IDomainServiceFactory defaultFactory)
        {
            _defaultFactory = defaultFactory;
        }
    
        public static void Setup()
        {
            if (!(DomainService.Factory is DomainServiceFactory))
            {
                DomainService.Factory = new DomainServiceFactory(DomainService.Factory);
            }
        }
    
        public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context)
        {
            if (domainServiceType == typeof(EmployeeService))
            {
                DomainServiceContext authServiceContext =
                    new DomainServiceContext(context, DomainOperationType.Query);
                AuthenticationService authService =
                    (AuthenticationService)_defaultFactory.CreateDomainService(typeof(AuthenticationService), authServiceContext);
                User user = authService.GetUser();
    
                DomainService domainService = (DomainService)Activator.CreateInstance(domainServiceType, user);
                domainService.Initialize(context);
                return domainService;
            }
            else
            {
                return _defaultFactory.CreateDomainService(domainServiceType, context);
            }
        }
    
        public void ReleaseDomainService(DomainService domainService)
        {
            if (domainService is EmployeeService)
            {
                domainService.Dispose();
            }
            else
            {
                _defaultFactory.ReleaseDomainService(domainService);
            }
        }
    }
    

    Setup Domain service factory

    protected void Application_Start(object sender, EventArgs e)
    {
        DomainServiceFactory.Setup();
    
    }
    
  • SQL Server Discovery

    The objective of this article is to discover the presence of Microsoft SQL Server  across subnet. There are API’s to enumerate SQL Server instances in single subnet (Win32 API : NetServerEnum ) and Microsoft enterprise manger uses this API to populate the list of SQL server available in current subnet. The API NetServerEnum broadcast UDP packets in the network and SQL server respond the message by sending their details. Since UDP packets can’t cross subnets and hence it will only return the partial list in particular domain.

    I was working on project where I have to find if on given IP or IP range , any sql server exists or not and if sql server exists I need to find the instance names. etc.

    The SQL server discovery module is hosted on web server and will be accessed by Silverlight application via WCF service. The code can be used to determine if SQL server is running or not (Before trying to connect) to build more responsive applications.

    The code sends the UDP packet (point to point access) directly to provide ip address on port 1434 and revived the data back from machines.

    If server is there the another function connects on TCP channel on TCP IP port to extract Sql server Netlib version.

    public class SqlServerInfo
    {
        public string ServerName { get; private set; }
        public string IpAddress { get; private set; }
        public string InstanceName { get; private set; }
        public bool IsClustered { get; private set; }
        public string Version { get; private set; }
        public int tcpPort { get; private set; }
        public string NamedPipe { get; private set; }
        public string Rpc { get; private set; }
        public bool IsActive { get; private set; }
    
        static public List<SqlServerInfo> DiscoverSQLServer(string[] possibleIPs, bool requiredDeepCheck)
        {
            List<SqlServerInfo> servers = new List<SqlServerInfo>();
            foreach (string ip in possibleIPs)
            {
                servers.AddRange(SqlServerInfo.DiscoverSQLServer(ip));
            }
            return servers;
        }
    
        static public List<SqlServerInfo> DiscoverSQLServer(string ip)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.EnableBroadcast = true;
            socket.ReceiveTimeout = 1000;
            List<SqlServerInfo> servers = new List<SqlServerInfo>();
            try
            {
                byte[] msg = new byte[] { 3 };
                IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), 1434);
                socket.SendTo(msg, ep);
                int cnt = 0;
                byte[] bytBuffer = new byte[64000];
                do
                {
                    cnt = socket.Receive(bytBuffer);
                    string s = System.Text.ASCIIEncoding.ASCII.GetString(bytBuffer, 3, BitConverter.ToInt16(bytBuffer, 1));
                    string[] parts = s.Split(new string[] { ";;" }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string s1 in parts)
                    {
                        SqlServerInfo sInfo = new SqlServerInfo(s1);
                        sInfo.IpAddress = ip;
                        if (sInfo.CheckIsActive())
                        {
                            servers.Add(sInfo);
                        }
    
                    }
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 300);
                } while (cnt != 0);
            }
            catch
            {
    
            }
            finally
            {
                socket.Close();
            }
    
            return servers;
        }
    
        private SqlServerInfo()
        {
    
        }
    
        public  string SSNetlibVersion(string remoteIP, int port)
        {
            string str = "";
            try
            {
                TcpClient client = new TcpClient();
                client.SendTimeout = 300;
                client.ReceiveTimeout = 300;
                client.Connect(remoteIP, port);
                NetworkStream stream = client.GetStream();
                byte[] buffer = new byte[] {
                    0x12, 1, 0, 0x34, 0, 0, 0, 0, 0, 0, 0x15, 0, 6, 1, 0, 0x1b,
                    0, 1, 2, 0, 0x1c, 0, 12, 3, 0, 40, 0, 4, 0xff, 8, 0, 1,
                    0x55, 0, 0, 0, 0x4d, 0x53, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0,
                    4, 8, 0, 0};
                stream.Write(buffer, 0, buffer.Length);
                byte[] buffer2 = new byte[0xff];
                string str2 = string.Empty;
                int count = stream.Read(buffer2, 0, buffer2.Length);
                str2 = Encoding.ASCII.GetString(buffer2, 0, count);
                string[] strArray = new string[] { buffer2[0x1d].ToString(), ".", buffer2[30].ToString(), ".", ((buffer2[0x1f] * 0x100) + buffer2[0x20]).ToString() };
                str = string.Concat(strArray);
                if (str.Substring(0, 1) == "0")
                {
                    str = "";
                }
            }
            catch
            {
            }
            return str;
        }
    
        private bool CheckIsActive()
        {
            string version= SSNetlibVersion(this.IpAddress, this.tcpPort);
            if (version.Length == 0)
            {
                this.IsActive = false;
                return false;
            }
            else
            {
                this.IsActive = true;
                this.Version = version;
                return true;
            }
    
        }
    
        private SqlServerInfo(string info)
        {
            string[] nvs = info.Split(';');
            for (int i = 0; i < nvs.Length; i += 2)
            {
                switch (nvs[i].ToLower())
                {
                    case "servername":
                        this.ServerName = nvs[i + 1];
                        break;
    
                    case "instancename":
    
                        this.InstanceName = nvs[i + 1];
                        break;
    
                    case "isclustered":
                        this.IsClustered = (nvs[i + 1].ToLower() == "yes");   //bool.Parse(nvs[i+1]);
                        break;
    
                    case "version":
                        this.Version = nvs[i + 1];
                        break;
    
                    case "tcp":
                        this.tcpPort = int.Parse(nvs[i + 1]);
                        break;
    
                    case "np":
                        this.NamedPipe = nvs[i + 1];
                        break;
    
                    case "rpc":
                        this.Rpc = nvs[i + 1];
                        break;
    
                }
            }
        }
    }

    using the code

    List<SqlServerInfo> sqlSrv = null;
    sqlSrv = SqlServerInfo.DiscoverSQLServer(address);
    //Or
    sqlSrv = SqlServerInfo.DiscoverSQLServer(
                        new string[]{ address+ ".01",
                            address+ ".02",
                            address+ ".03",
                            address+ ".04",
                            address+ ".05",
                            address+ ".06",
                            address+ ".07",
                            address+ ".08",
                            address+ ".09",
                            address+ ".10",
                            address+ ".21",
                            address+ ".51",
                            address+ ".100"},true);