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

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

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

SignalR


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

    • 前言
    • 配置Hub
    • 建立DrawingHub
    • 页面
    • javascript
    • 实现效果
    • 结束语
    • 参考文献

前言

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

配置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 下载

时间: 2024-10-04 20:51:23

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

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

原文:一步一步学习SignalR进行实时通信_5_Hub 一步一步学习SignalR进行实时通信\_5_Hub SignalR 一步一步学习SignalR进行实时通信_5_Hub 前言 Hub命名规则 Hub封装好的常用方法 Hub常用方法解释 保持状态 前后台交互 结束语 参考文献 前言 上一讲,我们简单的介绍了下Hub的配置以及实现方法,这一将我希望把更多的细节梳理清楚,不至于让大家在细节上面摸不着头脑,理解深了,那么做项目自然就会相对轻松一些. Hub命名规则 Hub与Persistent

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

原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 前言 关于start()的补充 跨域解决方案 JSONP CORS CORS跨域演示 结束语 参考文献 前言 这周工作比较忙,一直没有时间学习SignalR,大致希望一周能写一篇关于SignalR的文章.上一篇用Persistent Connections方式实现了个简单的在线

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

原文:一步一步学习SignalR进行实时通信_1_简单介绍 一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 前言 本来前几个月想写一系列的关于SignalR的文章,但是由于在做项目,时间非常的紧急,花了1天的时间大致了解了下SignalR,并实现了个在线聊天的小功能,本来记录一系列关于SignalR的文章,没想到写了MVC5使用SignalR进

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

原文:一步一步学习SignalR进行实时通信_2_Persistent Connections 一步一步学习SignalR进行实时通信\_2_Persistent Connections SignalR 一步一步学习SignalR进行实时通信_2_Persistent Connections 前言 安装 Persistent Connections 映射并配置持久连接 结束语 参考文献 前言 上一篇文章简单的介绍了下SignalR,从此篇文章就开始对SignalR进行剖析.在介绍Persiste

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

目录 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 建立连接 调用方法 维持状态 从服务器接收 结束语 参考文献 一步一步学习SignalR进行实时通信_7_非代理 标签(空格分隔): SignalR 前言 距离上次写博客已经一个多月了,一直想抽空写,却一直没时间写.现在紧接着要开始毕业设计了,工作的同时还要抽时间完成毕业设计,心也是有些累.由于自己是个.NET迷,自己的工作也是.net开发,老师给的毕业设计百分之八九十都是安卓java相关,虽然之前也学过但是自己还是喜

一步一步学习Vue(十一)

本篇继续学习vuex,还是以实例为主:我们以一步一步学Vue(四)中讲述的例子为基础,对其改造,基于vuex重构一遍,这是原始的代码: todolist.js ; (function () { var list = []; var Todo = (function () { var id = 1; return function (title, desc) { this.title = title; this.desc = desc; this.id = id++; } })(); /** *

一步一步跟我学习lucene(19)---lucene增量更新和NRT(near-real-time)Query近实时查询

这两天加班,不能兼顾博客的更新,请大家见谅. 有时候我们创建完索引之后,数据源可能有更新的内容,而我们又想像数据库那样能直接体现在查询中,这里就是我们所说的增量索引.对于这样的需求我们怎么来实现呢?lucene内部是没有提供这种增量索引的实现的: 这里我们一般可能会想到,将之前的索引全部删除,然后进行索引的重建.对于这种做法,如果数据源的条数不是特别大的情况下倒还可以,如果数据源的条数特别大的话,势必会造成查询数据耗时,同时索引的构建也是比较耗时的,几相叠加,势必可能造成查询的时候数据缺失的情况

一步一步跟我学习lucene(9)---lucene搜索之拼写检查和相似度查询提示(spellcheck)

suggest应用场景 用户的输入行为是不确定的,而我们在写程序的时候总是想让用户按照指定的内容或指定格式的内容进行搜索,这里就要进行人工干预用户输入的搜索条件了:我们在用百度谷歌等搜索引擎的时候经常会看到按键放下的时候直接会提示用户是否想搜索某些相关的内容,恰好lucene在开发的时候想到了这一点,lucene提供的suggest包正是用来解决上述问题的. suggest包联想词相关介绍 suggest包提供了lucene的自动补全或者拼写检查的支持: 拼写检查相关的类在org.apache.

一步一步学习IdentityServer3 (1)

学习之初: IdentityServer3我自己最开始了解到的就是做一个SSO单点登录,后面发现还有单独的认证服务功能,其实它还可以做APIs的访问控制,资源授权,另外还可以为提供第三方登录,其他的自由定制目前也在学习中. 网络飞速发展的今天,庞大的数据,庞大的用户,庞大的业务,都需要登录的支撑,登录授权完全看作一个单独的一门技术,Web端需要登录,App端需要登录,Api需要授权访问等等,除此以外大型业务系统,子系统之间其实也需要这样一个登陆授权,所以,登录不再是单一的一个功能点了,简单的查询