原文:一步一步学习SignalR进行实时通信_8_案例2

一步一步学习SignalR进行实时通信\_8_案例2

SignalR


前言

这讲分析一个案例,在一个画板上画画实时在其他客户端上显示。

配置Hub

在Startup中进行配置:

  1. public void Configuration(IAppBuilder app)
  2. {
  3. app.MapSignalR();
  4. }

建立DrawingHub

  1. public class Drawing : Hub
  2. {
  3. private const int BoardWidth = 300, BoardHeight = 300;
  4. private static int[,] _buffer = new int[BoardWidth, BoardHeight];
  5. public Task BroadcastPoint(int x, int y)
  6. {
  7. if (x < 0) x = 0;
  8. if (x >= BoardWidth) x = BoardWidth - 1;
  9. if (y < 0) y = 0;
  10. if (y >= BoardHeight) y = BoardHeight - 1;
  11. int color = 0;
  12. int.TryParse(Clients.Caller.color, out color);
  13. _buffer[x, y] = color;
  14. return Clients.Others.DrawPoint(x, y, Clients.Caller.color);
  15. }
  16. public Task BroadcastClear()
  17. {
  18. _buffer = new int[BoardWidth, BoardHeight];
  19. return Clients.Others.Clear();
  20. }
  21. public override Task OnConnected()
  22. {
  23. return Clients.Caller.Update(_buffer);
  24. }
  25. }

用一个二位数组来缓存画板,一共就三个方法

1. 当客户端连接时调用Update()方法刷新整个画板

2. BroadcastClear()是点击清除按钮时讲整个画板擦出

3. 最后一个就是画画方法,客户端按下鼠标画画时,调用该方法进行绘制。

页面

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <title>Drawing board</title>
  5. <script src="Scripts/jquery-1.6.4.min.js"></script>
  6. <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
  7. <script src="/signalr/js"></script>
  8. <script src="Scripts/DrawingBoard.js"></script>
  9. <style>
  10. div {
  11. margin: 3px;
  12. }
  13. canvas {
  14. border: 2px solid #808080;
  15. cursor: default;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div>
  21. <div>
  22. <label for="color">Color: </label>
  23. <select id="color">
  24. </select>
  25. </div>
  26. <canvas id="canvas" width="300" height="300"></canvas>
  27. <div>
  28. <button id="clear">Clear canvas</button>
  29. </div>
  30. </div>
  31. </body>
  32. </html>

页面非常简单,一个选择颜色的下拉框,一个画板,和一个清除按钮。

javascript

  1. $(function () {
  2. //初始化
  3. var colors = ["black", "red", "green", "blue", "yellow", "magenta", "white"];
  4. var canvas = $("#canvas");
  5. var colorElement = $("#color");
  6. for (var i = 0; i < colors.length; i++) {
  7. colorElement.append(
  8. "<option value='" + (i + 1) + "'>" + colors[i] + "</li>"
  9. );
  10. }
  11. //画板鼠标事件
  12. var buttonPressed = false;
  13. canvas.mousedown(function () {
  14. buttonPressed = true;
  15. })
  16. .mouseup(function () {
  17. buttonPressed = false;
  18. })
  19. .mousemove(function (e) {
  20. if (buttonPressed) {
  21. setPoint(e.offsetX, e.offsetY, colorElement.val());
  22. }
  23. });
  24. var ctx = canvas[0].getContext("2d");
  25. //画画
  26. function setPoint(x, y, color) {
  27. ctx.fillStyle = colors[color - 1];
  28. ctx.beginPath();
  29. ctx.arc(x, y, 2, 0, Math.PI * 2);
  30. ctx.fill();
  31. }
  32. //清除
  33. function clearPoints() {
  34. ctx.clearRect(0, 0, canvas.width(), canvas.height());
  35. }
  36. $("#clear").click(function () {
  37. clearPoints();
  38. });
  39. //signalR
  40. var hub = $.connection.drawingBoard;
  41. //缓存颜色
  42. hub.state.color = colorElement.val();
  43. var connected = false;
  44. //改变颜色
  45. colorElement.change(function () {
  46. hub.state.color = $(this).val();
  47. });
  48. //当连接时且鼠标按下时调用
  49. canvas.mousemove(function (e) {
  50. if (buttonPressed && connected) {
  51. hub.server.broadcastPoint(
  52. Math.round(e.offsetX), Math.round(e.offsetY)
  53. );
  54. }
  55. });
  56. $("#clear").click(function () {
  57. if (connected) {
  58. hub.server.broadcastClear();
  59. }
  60. });
  61. hub.client.clear = function () {
  62. clearPoints();
  63. };
  64. hub.client.drawPoint = function (x, y, color) {
  65. setPoint(x, y, color);
  66. };
  67. //更新整个画板
  68. hub.client.update = function (points) {
  69. if (!points) return;
  70. for (var x = 0; x < 300; x++) {
  71. for (var y = 0; y < 300; y++) {
  72. if (points[x][y]) {
  73. setPoint(x, y, points[x][y]);
  74. }
  75. }
  76. }
  77. };
  78. $.connection.hub.start()
  79. .done(function () {
  80. connected = true;
  81. });
  82. });

实现效果

结束语

简单的讲了一个小案例。

源码下载

本文发布至作业部落

参考文献

SignalR Programming in Microsoft ASP.NET pdf 下载

一步一步学习SignalR进行实时通信_8_案例2的更多相关文章

  1. 一步一步学习SignalR进行实时通信_6_案例

    原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...

  2. 一步一步学习SignalR进行实时通信_1_简单介绍

    一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 ...

  3. 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序

    原文:一步一步学习SignalR进行实时通信_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信\_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信_9_托管在非We ...

  4. 一步一步学习SignalR进行实时通信_7_非代理

    原文:一步一步学习SignalR进行实时通信_7_非代理 一步一步学习SignalR进行实时通信\_7_非代理 SignalR 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 ...

  5. 一步一步学习SignalR进行实时通信_5_Hub

    原文:一步一步学习SignalR进行实时通信_5_Hub 一步一步学习SignalR进行实时通信\_5_Hub SignalR 一步一步学习SignalR进行实时通信_5_Hub 前言 Hub命名规则 ...

  6. 一步一步学习SignalR进行实时通信_4_Hub

    原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...

  7. 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域

    原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_ ...

  8. 一步一步学习SignalR进行实时通信_2_Persistent Connections

    原文:一步一步学习SignalR进行实时通信_2_Persistent Connections 一步一步学习SignalR进行实时通信\_2_Persistent Connections Signal ...

  9. 12.Linux软件安装 (一步一步学习大数据系列之 Linux)

    1.如何上传安装包到服务器 有三种方式: 1.1使用图形化工具,如: filezilla 如何使用FileZilla上传和下载文件 1.2使用 sftp 工具: 在 windows下使用CRT 软件 ...

随机推荐

  1. 关于TXT转CHM的完整解决方式

    为什么要转CHM? 有些书,TXT的资源非常好找,而CHM的资源非常难找(先不论PDF格式的,只是话说PDF格式的没有一个书签文件夹看起来也非常难受) 而CHM格式在左側有一个文件夹结构,我最喜欢这个 ...

  2. Android中GridView拖拽的效果

    最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的那么 ...

  3. Qt 学习之路 2(80):定位器

    QML 提供了很多用于定位的元素.这些元素叫做定位器,都包含在 QtQuick 模块.这些定位器主要有 Row.Column.Grid和Flow等. 为了介绍定位器,我们先添加三个简单的组件用于演示: ...

  4. Java设计模式05:常用设计模式之原型模式(创建型模式)

    1. Java之原型模式(Prototype Pattern)     原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. ...

  5. .NET中TextBox控件设置ReadOnly=true后台取不到值三种解决方法

    当TextBox设置了ReadOnly=true后要是在前台为控件添加了值,后台是取不到的,值为空,多么郁闷的一个问题经过尝试,发现可以通过如下的方式解决这个问题.感兴趣的朋友可以了解下 当TextB ...

  6. C++前置++与后置++的区别与重载

    ++属于单目运算符,前置与后置的实现代码不一样,下面以整数自增为例: // 前置++,返回自增后的值,且返回的是一个左值 int& operator++(){ *this += 1; retu ...

  7. Qt经典出错信息之”Basic XLib functionality test failed!”

    解决方法: 此完整出错信息是在./configure阶段Basic XLib functionality test failed!You might need to modify the includ ...

  8. 常见的iis日志代码!

    2xx  成功 200  正常:请求已完成. 201  正常:紧接 POST 命令. 202  正常:已接受用于处理,但处理尚未完成. 203  正常:部分信息 — 返回的信息只是一部分. 204   ...

  9. spring配置中引入properties

    <context:property-placeholder location="classpath*:db.properties" />

  10. iOS图片的伪裁剪(改变图片的像素值)

    0x00 原理 利用一张图片事先画好的图片(以下称为蒙板),盖在要被裁剪的的图片上,然后遍历蒙板上的像素点,修改被裁剪图片对应位置的像素的色值即可得到一些我们想要的不规则图片了(比如人脸) 0x01 ...