Simple Drawing in SignalR Using Visual Studio 2012

This article shows a simple way to draw in SignalR using .NET and Visual Studio 2012.

Introduction

This sample shows the uses of mouse events on HTML5 Canvas and broadcasts the drawing to all clients using SignalR.

Tools used

  • .NET 4.5
  • SignalR
  • jQuery
  • HTML5
What SignalR is

ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.

Output  

To test the output, run the application from multiple HTML5 compatible browsers or windows. 
 
 
 
Let us have a look to the code given below.

Step 1

Create a new project as in the following:
  

 
Step 2

Install the SignalR package from the Nuget Package console as in the following:
 
Step 3
 
Add a new class named DrawDot.cs as in the following:
 
 
 
DrawDot.cs
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using Microsoft.AspNet.SignalR;  
  6. namespace SignalRSample  
  7. {  
  8.     public class DrawDot: Hub   
  9.     {  
  10.         public void UpdateCanvas(int x, int y)  
  11.         {  
  12.             Clients.All.updateDot(x, y);  
  13.         }  
  14.         public void ClearCanvas() {  
  15.             Clients.All.clearCanvas();  
  16.         }  
  17.     }  
  18. }  
Step 4
 
Add a new Class named Startup.cs as in the following:

 
 
Startup.cs 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using Microsoft.Owin;  
  6. using Owin;  
  7. [assembly: OwinStartup(typeof(SignalRSample.Startup))]  
  8. namespace SignalRSample  
  9. {  
  10.     public class Startup  
  11.     {  
  12.         public void Configuration(IAppBuilder app)  
  13.         {  
  14.             // Any connection or hub wire up and configuration should go here      
  15.             app.MapSignalR();  
  16.         }  
  17.   
  18.     }  
  19. } 
Step 5

Add a new HTML file named index.html and add the code below.

Include jQuery Script and SignalR Client JavaScript.

 
 
 
  • Include jQuery Script and SignalR Client JavaScript.

  • Path for dynamic ../Scripts/Hubs folder.

  • Create drawDot Hub Server connection.

  • The UpdateDot function is called from the server to update the drawing on the canvas (NOTE: In the server code, the updateDot is in camelCase like UpdateDot).

  • ClearCanvas function called by the Server to clear the canvas. (NOTE: In Server code, the clearCanvas is in camelCase like ClearCanvas).

  • OnMouseMove and OnMouseDown calls the updateCanvas Server function.
Complete index.html
  1. <!DOCTYPE html>    
  2. <html    
  3.     xmlns="http://www.w3.org/1999/xhtml">    
  4.     <head>    
  5.         <title>SignalR Sketchpad</title>    
  6.         <script src="Scripts/jquery-1.6.4.min.js"></script>    
  7.         <script src="Scripts/jquery.signalR-2.2.0.js"></script>    
  8.         <script src="/signalr/hubs"></script>    
  9.         <script type="text/javascript">     
  10. //Create the SignalR Connection     
  11. var DOT = $.connection.drawDot;     
  12. //Start the SignalR hub     
  13. $.connection.hub.start().done();     
  14. //Function called from DrawDot Server     
  15. DOT.client.updateDot = function (x, y) {     
  16. drawDot(x, y, 8);     
  17. };     
  18. //Function called from DrawDot Server     
  19. DOT.client.clearCanvas = function (x, y) {     
  20. clearCanvas();     
  21. };     
  22. //////////////////////////////////////////////////////     
  23. // Variables for referencing the canvas and 2dcanvas context     
  24. var canvas, ctx;     
  25. // Variables to keep track of the mouse position and left-button status     
  26. var mouseX, mouseY, mouseDown = 0;     
  27. // Draws a dot at a specific position on the supplied canvas name     
  28. // Parameters are: A canvas context, the x position, the y position, the size of the dot     
  29. function drawDot(x, y, size)    
  30. {     
  31. // Let's use black by setting RGB values to 0, and 255 alpha (completely opaque)     
  32. r = 0g = 0b = 0a = 255;     
  33. // Select a fill style     
  34. ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";     
  35. // Draw a filled circle     
  36. ctx.beginPath();     
  37. ctx.arc(x, y, size, 0, Math.PI * 2, true);     
  38. ctx.closePath();     
  39. ctx.fill();     
  40. }     
  41. // Clear the canvas context using the canvas width and height     
  42. function cleanCanvas()     
  43. {     
  44. clearCanvas();     
  45. DOT.server.clearCanvas();     
  46. }     
  47. function clearCanvas()     
  48. {     
  49. ctx.clearRect(0, 0, canvas.width, canvas.height);     
  50. }     
  51. // Keep track of the mouse button being pressed and draw a dot at current location     
  52. function sketchpad_mouseDown()    
  53. {     
  54. mouseDown = 1;     
  55. drawDot(mouseX, mouseY, 8);     
  56. DOT.server.updateCanvas(mouseX, mouseY);     
  57. }     
  58. // Keep track of the mouse button being released     
  59. function sketchpad_mouseUp()     
  60. {     
  61. mouseDown = 0;     
  62. }     
  63. // Keep track of the mouse position and draw a dot if mouse button is currently pressed     
  64. function sketchpad_mouseMove(e)    
  65. {     
  66. // Update the mouse co-ordinates when moved     
  67. getMousePos(e);     
  68. // Draw a dot if the mouse button is currently being pressed     
  69. if (mouseDown == 1)     
  70. {     
  71. drawDot(mouseX, mouseY, 8);     
  72. DOT.server.updateCanvas(mouseX, mouseY);     
  73. }     
  74. }     
  75. // Get the current mouse position relative to the top-left of the canvas     
  76. function getMousePos(e)    
  77. {     
  78. if (!e)     
  79. var e = event;     
  80. if (e.offsetX)     
  81. {     
  82. mouseX = e.offsetX;     
  83. mouseY = e.offsetY;     
  84. }     
  85. else if (e.layerX)    
  86. {     
  87. mouseX = e.layerX;     
  88. mouseY = e.layerY;     
  89. }     
  90. }     
  91. // Set-up the canvas and add our event handlers after the page has loaded     
  92. function init()     
  93. {     
  94. // Get the specific canvas element from the HTML document     
  95. canvas = document.getElementById('sketchpad');     
  96. // If the browser supports the canvas tag, get the 2d drawing context for this canvas     
  97. if (canvas.getContext)     
  98. ctx = canvas.getContext('2d');     
  99. // Check that we have a valid context to draw on/with before adding event handlers     
  100. if (ctx)     
  101. {     
  102. // React to mouse events on the canvas, and mouseup on the entire document     
  103. canvas.addEventListener('mousedown', sketchpad_mouseDown, false);     
  104. canvas.addEventListener('mousemove', sketchpad_mouseMove, false);     
  105. window.addEventListener('mouseup', sketchpad_mouseUp, false);     
  106. }     
  107. else    
  108. {     
  109. document.write("Browser not supported!!");     
  110. }     
  111. }     
  112. </script>    
  113.         <style>     
  114. /* Some CSS styling */     
  115. .rightside    
  116. {     
  117. float: left;     
  118. margin-left: 10px;     
  119. }     
  120. #sketchpad     
  121. {     
  122. float: left;     
  123. height: 300px;     
  124. width: 400px;     
  125. border: 2px solid #888;     
  126. border-radius: 4px;     
  127. position: relative; /* Necessary for correct mouse co-ords in Firefox */     
  128. }     
  129. #clear_button, #save_button    
  130. {     
  131. float: left;     
  132. font-size: 15px;     
  133. padding: 10px;     
  134. -webkit-appearance: none;     
  135. background: #eee;     
  136. border: 1px solid #888;     
  137. margin-bottom: 5px;     
  138. }     
  139. </style>    
  140.     </head>    
  141.     <body >    
  142.         <div id="sketchpadapp">    
  143.             <div class="rightside">    
  144.                 <input type="submit"     
  145. value="Clear Canvas" id="clear_button" />    
  146.                 <br />    
  147.                 <canvas id="sketchpad" height="300"     
  148. width="400"></canvas>    
  149.             </div>    
  150.         </div>    
  151.     </body>    
  152. </html>    

References