D.O.T.S. -状态的分布式混淆传输(译文)
By S.F.
本文链接 https://www.kyfws.com/news/d-o-t-s-distributed-obfuscated-transmission-of-sta/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 26 分钟阅读 - 12796 个词 阅读量 0D.O.T.S. -状态的分布式混淆传输(译文)
原文地址:https://www.codeproject.com/Articles/586965/D-O-T-S-Distributed-Obfuscated-Transmission-of-Sta
原文作者:Henry Sheldon
译文由本站翻译
前言
An study in communication across multiple technologies using Azure cloud services, all based on a centralized informational domain. 使用Azure云服务跨多种技术进行通信的一项研究,所有这些都基于集中式信息域.
Table of Context(上下文)
*I Introduction *
我介绍
*II Website and Source *
II 网站和源代码
Website and Source (网站和来源)
- D.O.T.S. Website on Azure - http://d-o-t-s.azurewebsites.netD.O.T.S. Azure上的网站-http://d-o-t-s.azurewebsites.net
- Challenge 2 Source Code - The Website挑战2源代码-网站
- Challenge 3 Source Code - The Database Access Layer挑战3源代码-数据库访问层
Introduction (介绍)
Communication - exchange of information: the exchange of information between people, e.g. by means of speaking, writing, or using a common system of signs or behavior.
交流-信息交流:人与人之间的信息交流,例如通过说话,书写或使用常见的标志或行为系统.
D.O.T.S. is a systematic relationship of simple colored and textured circles (dots) which are used as a common system of signs to help two or more people or systems to communicate anonymously.
D.O.T.S.是简单的彩色和带纹理的圆圈(点)的系统关系,这些圆圈用作常见的符号系统,以帮助两个或多个人或系统进行匿名通信.
DOTS is fundamentally a very simple idea. At the core of the project will be a 3 x 3 grid of circles that can be clear or hold up to three colored and textured patterns. This grid when loaded with a pre-determined pattern can transmit a coded message between two ore more participants as long as all participants are aware of the pattern.
从根本上说,DOTS是一个非常简单的想法.该项目的核心将是一个3 x 3的圆形网格,该网格可以清晰或最多包含三个彩色和纹理图案.只要所有参与者都知道该模式,此网格在加载了预定模式后便可以在两个或更多参与者之间传输编码消息.
Challenge 1 - Overview - The Plan
挑战1-概述-计划
This article is being written as a submission to the 2013 CodeProject Azure Challenge.
本文是作为2013 CodeProject Azure挑战的提交而撰写的.
DOTS, while simple in idea, holds a larger challenges. There will be many different interfaces that will be available to the final project. I’m hoping to have the website, a mobile app, many types of API’s using many technologies such as HTML, JavaScript, Web API, and WCF all hosted and backed by Azure. The plan is that while DOTS will have a base website, it will be able either interactively or read-only to almost any technology that can be linked to the cloud.
DOTS虽然思路简单,但挑战更大.最终项目将有许多不同的接口可用.我希望网站,移动应用程序,使用许多技术的多种类型的API(例如HTML,JavaScript,Web API和WCF)都由Azure托管和支持.该计划是,尽管DOTS将拥有一个基础网站,但它将能够以交互方式或只读方式访问几乎所有可链接到云的技术.
There can be endless uses for DOTS as a communication protocol. A website could have an imbedded DOTS map to show a system status; corporate employees could use DOTS to convey messages that they don’t want in writing; lovers could whisper sweet nothings as only symbols. The ideas are endless. I’m hoping to demonstrate how the DOTS protocol can be defined to make much larger applications on top of the pre-determined DOTS maps.
DOTS作为通信协议可能有无数用途.一个网站可以嵌入DOTS映射以显示系统状态.公司员工可以使用DOTS传达他们不希望的书面信息;恋人可以低声说些甜蜜的东西,仅作为象征.这些想法是无止境的.我希望演示如何在预定的DOTS映射之上定义DOTS协议以使更大的应用程序成为可能.
First Challenge: Getting Started
首要挑战:入门
This Article
本文
Second Challenge : Building a website
第二个挑战:建立一个网站
This website will not be hooked to a database so I’m hoping to get the JavaScript, Mobile first responsive design (CSS), and possibly the start of how to use Web API hooked up during this challenge. While the site will be based in HTML5, I am planning on using JavaScript to make sure older browsers have accessibility to the site.
该网站不会被连接到数据库,因此我希望获得JavaScript,移动优先响应设计(CSS),以及在此挑战期间可能如何连接Web API的开始.虽然该站点将基于HTML5,但我计划使用JavaScript来确保较旧的浏览器可访问该站点.
Third Challenge : Using SQL on Azure
第三个挑战:在Azure上使用SQL
In this challenge I will hookup the social network part of DOTS. Users will be able to anonymously register and make a new groups to share their DOTS maps. There will be an easy way for other users to join a DOTS group without registering. Any one in the group will have access to the DOTS map. DOTS will not have access rights by design because of the equal access design it will possess.
在这个挑战中,我将介绍DOTS的社交网络部分.用户将能够匿名注册并创建新的组以共享其DOTS地图.其他用户无需注册即可轻松加入DOTS组.群组中的任何人都可以访问DOTS地图.由于DOTS具有平等的访问设计,因此其在设计上不会具有访问权.
Forth Challenge: Virtual Machines
第四项挑战:虚拟机
In this challenge I will setup my windows azure services that will clean up the DOTS groups as well as the WCF services which I will use as an API for the Mobile Challenge and as a general access point.
在此挑战中,我将设置Windows Azure服务以清理DOTS组以及WCF服务,这些服务将用作移动挑战的API和一般访问点.
Fifth Challenge: Mobile Access
第五大挑战:移动访问
The mobile app will be aimed at the Windows 8 phone (because that’s what I own) but will use JavaScript, Web API, or WCF calls to interact with Azure. My goal here is not to tie it to any one operation system so I will try to keep it as generic HTML5 and JavaScript. This will make it easy to transition to the app to many mobile environments.
该移动应用程序将针对Windows 8手机(因为这是我拥有的),但将使用JavaScript,Web API或WCF调用与Azure进行交互.我的目标不是将其绑定到任何一个操作系统上,因此我将尝试将其保留为通用HTML5和JavaScript.这将使轻松过渡到许多移动环境的应用程序.
I’m new to Mobile Apps so this will be the hardest challenge for me to tackle.
我是移动应用程序的新手,所以这将是我要应对的最困难的挑战.
Challenge 2 - D.O.T.S. Website(挑战2-D.O.T.S.网站)
- *D.O.T.S. Website on Azure - http://d-o-t-s.azurewebsites.net/ - “C” if you can find the Easter Egg.*D.O.T.S. Azure上的网站-http://d-o-t-s.azurewebsites.net/-如果您可以找到复活节彩蛋,则单击" C".
Easter Egg
复活节彩蛋
My Easter Egg has Bob spinning for the Dots and Talking. To see him, make a Green letter C with the DOTS filled in with Blue like the image below. The Easter Egg that pops up is NOT a animated PNG. It is done with jQuery Rotate plugin and is all JavaScript. I ran out of time so I didn’t expand on how I did it in the article but check out the source code above if you are interested.
我的复活节彩蛋中,鲍勃为点子和说话而旋转.要见他,请用绿色字母C制作一个DOTS,并用蓝色填充DOTS,如下图所示.弹出的复活节彩蛋不是PNG动画.它是使用jQuery Rotate插件完成的,并且全部是JavaScript.我没有时间了,所以在本文中我没有做更多的扩展,但是如果您感兴趣的话,请查看上面的源代码.
Key Principle and Building Style(关键原理和建筑风格)
*Source Code *
源代码
I purposely did this first challenge as a very basic website. I didn’t put it into the larger framework so I could show how powerful javascript and css are by themselves. From here on out my source will be within a much larger framework (probably MVC 4).
作为一个非常基本的网站,我有意进行了第一个挑战.我没有将其放入更大的框架中,因此我可以展示它们本身具有多么强大的javascript和css.从这里开始,我的资源将在更大的框架(可能是MVC 4)中.
*Domain-driven Design *
领域驱动设计
Domain-driven Design is not a methodology, framework, or design pattern per se. It’s more of a way of thinking. It puts the focus on the domain logic and all work is centering around that logic. It’s just a way to make sure all design is focused at a central goal.
域驱动的设计本身并不是方法论,框架或设计模式.这更多是一种思维方式.它把重点放在域逻辑上,所有工作都围绕该逻辑进行.这只是确保所有设计都集中在一个中心目标上的一种方法.
The DOTS project’s main design principle is going to be the extensible model of the protocol based on technology. By doing the front end website first, I needed to make sure there was the ability to wrap it into a larger framework and hook it up to a database and other technology. For this reason, I concentrated heavily on CSS, JavaScript, and the basic way the DOTS mapping will be work.
DOTS项目的主要设计原理将是基于技术的协议的可扩展模型.通过首先访问前端网站,我需要确保能够将其包装到更大的框架中并将其连接到数据库和其他技术.由于这个原因,我集中精力研究CSS,JavaScript和DOTS映射的基本工作方式.
*Frameworks / Extensibility *
框架/可扩展性
Wherever possible I will try to use Buy versus Build methods of designing. I try to only use well known 3rd party frameworks most of the time. In this article I will stick to only using open source frameworks except for Microsoft Azure, .NET, and Visual Studio products.
我将尽可能尝试使用"购买"与"构建"设计方法.我尝试大多数时候只使用众所周知的第三方框架.在本文中,我将坚持只使用开放源代码框架,但Microsoft Azure,.NET和Visual Studio产品除外.
HTML5 Design(HTML5设计)
HTML5 has given us a bunch of new tools for web developing. Many of these new extensions are in response to new dynamic areas happening in the website world. In the past, we would design a website to be viewed on a computer and computer monitor only. In today’s world, we need the website to be available through many types of media viewers such as phones, tablets, hybrids, as well as the desktop. The websites also need to have a much stronger client side presence with the clients (browsers) doing a lot more work than ever in the past.
HTML5为我们提供了许多用于Web开发的新工具.这些新扩展中的许多响应于网站世界中发生的新动态领域.过去,我们设计的网站只能在计算机和计算机显示器上查看.在当今世界,我们需要可以通过多种类型的媒体查看器(例如电话,平板电脑,混合动力设备以及台式机)访问该网站.网站还需要拥有更强大的客户端功能,客户端(浏览器)要比过去做更多的工作.
*Article’s Assumptions *
文章的假设
Because of the contest’s time challenges, I can not go into every term and it’s meanings so this article will be geared toward the intermediate or advanced web developer. I’m going to assume the reader has basic knowledge HTML, CSS, JavaScript, and maybe jQuery. I will try to show examples and show the frameworks that are used. Mostly it will be an overview and when time permits I will get into some of the cooler coding of some functions. Feel free to contact me in the future, if someone would like me to elaborate on why or how I did something specific.
由于竞赛面临时间挑战,因此我无法逐一讨论所有术语及其含义,因此本文将针对中级或高级Web开发人员.我将假设读者具有HTML,CSS,JavaScript以及jQuery的基本知识.我将尝试显示示例并显示所使用的框架.通常,这是一个概述,并且在时间允许的情况下,我将介绍某些功能的一些较酷的编码.如果有人希望我详细说明我为什么或如何做某件事,请随时与我联系.
CSS and Responsive Design(CSS和响应式设计)
*Responsive design is the idea to make sure the web pages have a clean look on any type of media without writing a new website for each device. The CSS styles around responsive design are known as media queries. Before we dive into those, let’s discuss a very popular framework that does a lot more then responsive design; Twitter Bootstrap. *
响应式设计的目的是确保网页在任何类型的媒体上都具有清晰的外观,而无需为每个设备编写新的网站.围绕响应式设计的CSS样式称为媒体查询.在深入探讨这些内容之前,让我们讨论一个非常流行的框架,该框架所要做的远远超过了响应式设计. Twitter引导程序.
*Twitter Bootstrap *
Twitter的引导
Twitter Bootstrap is an awesome set of interface elements, CSS layouts, and JavaScript tools packaged together and freely available to use for website design. If anyone is designing a new website, I highly encourage you to take a look at this framework. I’m sure you will find something of use inside it.
Twitter Bootstrap是一组很棒的界面元素,CSS布局和JavaScript工具,打包在一起,可以免费用于网站设计.如果有人要设计一个新网站,我强烈建议您看看这个框架.我相信您会在其中找到有用的东西.
Twitter Bootstrap Scaffolding is part of the framework that helps a developer setup responsive design and is the first key technology I used in the website. Scaffolding uses a 12 column grid system that will try to keep sections of your webpage together, defined by specific Bootstrap classes. As a webpage’s width becomes smaller, the groupings from the right will fall below the groupings on the left until finally all groups are lined up. This way smaller devices you read the webpage from top to bottom where as on a monitor, group of elements can be read left to right then up and down.
Twitter Bootstrap脚手架是框架的一部分,可帮助开发人员设置响应式设计,这是我在网站中使用的第一项关键技术.脚手架使用12列网格系统,该系统将尝试将网页的各个部分保持在一起,这由特定的Bootstrap类定义.随着网页宽度的变小,从右侧开始的分组将落在左侧的分组之下,直到最后所有分组都排成一行.这样,较小的设备就可以从上到下阅读网页,就像在显示器上一样,可以从左到右然后向上和向下读取元素组.
Bootstrap Scaffolding responsive functions also offer predefined CSS/JavaScript classes that will hide or show sections of code based on if they are intended for certain types of media. This is very cool for easily defining to show and hide based on the device you are designing for. I didn’t use these classes that much on the initial website only because I want to demonstrate different ideas of how to use media queries.
Bootstrap脚手架响应功能还提供了预定义的CSS/JavaScript类,这些类将根据其是否适用于某些类型的媒体来隐藏或显示代码段.这很酷,可以轻松地根据要设计的设备定义显示和隐藏.在最初的网站上,我没有太多使用这些类,只是因为我想展示有关如何使用媒体查询的不同想法.
*Degradation vs. Mobile First CSS *
降级与Mobile First CSS
Both Mobile First and Degradation responsive design is the idea to use CSS3 Media Tags to change the design look and feel based on the width of the page. The idea of degradation is to first code the Default Layout for larger media like a desktop, and then use the media queries to adjust the layout in smaller widths. Mobile first design on the other hand typically progresses further in design in each media query as the browser grows larger. Think of Mobile First as progressive enhancement of the CSS where with Degradation, you are starting with the full CSS and gracefully taking away the styles you do not need in smaller widths. Both of these design patterns are useful and should be considered based on the need of the project.
“移动优先"和"降级"响应式设计都是使用CSS3媒体标签根据页面的宽度更改设计外观的想法.降级的想法是先为较大的媒体(如台式机)编码默认布局,然后使用媒体查询将布局调整为较小的宽度.另一方面,随着浏览器的变大,移动优先设计通常会在每个媒体查询的设计中进一步发展.可以将Mobile First视为CSS的逐步增强,而通过Degradation,您将从完整的CSS开始,并以较小的宽度优雅地删除不需要的样式.这两种设计模式都是有用的,应根据项目的需要加以考虑.
The main reason I chose degradation over mobile first is because older browsers such as IE 6-8 do not recognize media queries so the user will see the full site rather then mobile version of it. There are JavaScript libraries that will give these older browsers the ability to use media queries but I just choose not to use them unless needed.
我选择降级优先于移动设备的主要原因是因为IE 6-8等较旧的浏览器无法识别媒体查询,因此用户将看到整个网站,而不是移动网站.有JavaScript库将使这些较旧的浏览器能够使用媒体查询,但除非有必要,否则我只是选择不使用它们.
Below shows how the media queries work in the CSS file. The default website CSS goes on top and then each change for Table, Wide Mobile, and Non-smart phones will go underneath.
下面显示了媒体查询在CSS文件中的工作方式.默认网站CSS位于顶部,然后对Table,Wide Mobile和Non-smart手机的每次更改都位于下方.
/* Tablet Layout: 768px.
-----------------------------------------------------------------
*/
@media only screen and (min-width: 768px) and (max-width: 991px) {
<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">}
<span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment">/* Wide Mobile Layout: 480px.
------------------------------------------------------------
*/
@media only screen and (min-width: 480px) and (max-width: 767px) {
<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">}
<span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment"><span class="code-comment">/* Misc Small Mobile Mobile Layout: < 480px.
------------------------------------------------------------
*/
@media only screen and (min-width: 1px) and (max-width: 479px) {
<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">}</span></span></</</span>span></</span></</span>span>span></</span>
*JavaScript - When CSS isn’t enough *
JavaScript-CSS不够用时
Responsive design mainly deals with the width of the site because scrolling down is usually not a problem. However, on my DOTS site, I purposely added a footer so I could show how to drop a element if it collides with another element. This is one area that is important to know how to do but can’t always be done with CSS.
自适应设计主要处理站点的宽度,因为向下滚动通常不是问题.但是,在我的DOTS站点上,我有意添加了页脚,因此我可以显示如何删除与另一个元素碰撞的元素.这是一个重要的领域,知道如何做,但CSS并不总是可以做到的.
Basic HTML Footer
基本HTML页脚
<div class="footer">
<div>
© DOTS 2013. All Rights Reserved
</div>
</div>
Footer CSS. Notice in this css code, an absolute position with the bottom of 0 and a width of 100% of the screen forces this footer to always stay at the bottom.
页脚CSS.请注意,在此CSS代码中,底部为0且屏幕宽度为100%的绝对位置会强制此页脚始终位于底部.
/*------------------------- Footer -------------------------*/
.footer {
position<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:100%<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
height<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:50px<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">; /* Height of the footer */
margin<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:0 10px<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
padding<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:0<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">}</span></</span></span></span></span></span></span></span></</span>
Javascript to hide footer if goes over the .dotsTable class.
如果遍历.dotsTable类,则用于隐藏页脚的Javascript.
$(function () {
/* Hide Footer if window goes over the Dots Table */
$(window).resize(function() {
$('.footer').show();
var dotsTable = $(".dotsTable");
var tablebottom = dotsTable.position().top + dotsTable.height();
var footertop = $(".footer").position().top;
if (footertop <= tablebottom)
$('.footer').hide();
});
});
In the above jQeury code, notice I first make sure the footer is shown. You can’t get a position of an object if it’s hidden. jQuery has a position function that returns the top and left pixels of where the element is within the DOM window. By adding the height function to this value, you can get the bottom which I do here on the dotsTable.
在上面的jQeury代码中,请注意我首先确保显示了页脚.如果对象是隐藏的,则无法获得其位置. jQuery具有position函数,该函数返回DOM窗口中元素所在位置的顶部和左侧像素.通过将height函数添加到此值,您可以在dotsTable上获得我在此处所做的底部.
I then test to see if the top of the footer is above the table bottom and if it is I then hide it. It’s pretty straight forward code but important when testing and fixing elements that cross each other during a window resize.
然后,我测试看一下页脚的顶部是否在桌子底部上方,如果是,则将其隐藏.这是非常简单的代码,但是在测试和修复在调整窗口大小时相互交叉的元素时很重要.
JavaScript - DOTS Map (JavaScript-点地图)
The DOTS map is a simple HTML table. I decided not to use
<img>
tags for the buttons but instead put the buttons as background images. This is a lot better because the table becomes responsive and let’s the images grow and shrink with it but there’s a trick to making this happen. Let me show this in the HTML and CSS that let’s this functionality happen.
DOTS映射是一个简单的HTML表.我决定不对按钮使用<img>
标签,而是将按钮作为背景图像.这要好得多,因为表格变得响应灵敏,让图像随其增长和缩小,但是有一种技巧可以做到这一点.让我在HTML和CSS中显示这一功能.
*The HTML is extremely simple which is the goal for HTML5 page design. Notice it’s just a blank table with no content. *
HTML非常简单,这是HTML5页面设计的目标.请注意,这只是一个没有内容的空白表.
<div class='dotsMap'>
<div id="dotsSelect">
<table class="dotsTable">
<tr>
<td id="r1c1"></td>
<td id="r1c2"></td>
<td id="r1c3"></td>
</tr>
<tr>
<td id="r2c1"></td>
<td id="r2c2"></td>
<td id="r2c3"></td>
</tr>
<tr>
<td id="r3c1"></td>
<td id="r3c2"></td>
<td id="r3c3"></td>
</tr>
</table>
</div>
<div id="colorSelect">
Select color
<div class="colors" id="red"></div>
<div class="colors" id="green"></div>
<div class="colors" id="blue"></div>
</div>
</div>
Here’s the CSS responsible for the default background dots. Please notice here that we make the background images of each have the background-size style of ‘contain’. This allows the images to grow or shrink with the sizing of the cell. It’s a nice way to make the table truly responsive. Alternatively, if we put
<img>
tags inside the cells, we would have to use JavaScript or substitute new images based on certain widths.
这是负责默认背景点的CSS.请注意,在此我们使每个的背景图像的背景尺寸样式为’contain'.这允许图像随着单元格的大小而增长或缩小.这是使表格真正响应的好方法.另外,如果我们在单元格中放置标签,则必须使用JavaScript或根据特定宽度替换新图像.
.dotsTable tr td {
background<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:url(../images/dots/silverDot.png)<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
background-size<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">:contain<<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
width<<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">: 124px<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
height<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">: 124px<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">;
<span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none"><span class="code-none">}</span></</span></span></span></span></span></span></span></</span>
*From here the jQuery takes over and gives us the full functionality of changing the dot’s colors. The 3 events trigger the DOTS to be set are mousedown, mouseenter, and mouseup. These are all mouse events so currently only the mouse on the desktop or a finger on a touch screen will be able to set the dots. I’m considering ideas of how to let a keyboard select the dots in the future but for now it’s not possible. *
jQuery从这里开始接管工作,并为我们提供了更改点的颜色的全部功能.触发设置DOTS的3个事件是mousedown,mouseenter和mouseup.这些都是鼠标事件,因此当前只有台式机上的鼠标或触摸屏上的手指才能设置点.我正在考虑将来如何让键盘选择点的想法,但目前还不可能.
/* dot definitions */
var _imgFolder = "./images/dots/";
var _silverDot = "silverDot.png";
var _redDot = "redDot.png";
var _greenDot = "greenDot.png";
var _blueDot = "blueDot.png";
/* defaulting variables */
var _mouseDown = 0;
var _currentColor = "rgb(255, 0, 0)";
/* Mouse Down - Start our new object */
$(function () {
$('.dotsTable td')
.mousedown(function () {
_mouseDown = 0;
var silverPath = (_imgFolder + _silverDot);
var img = _redDot;
if (_currentColor == 'rgb(255, 0, 0)')
img = _redDot;
else if (_currentColor == 'rgb(0, 128, 0)')
img = _greenDot;
else if (_currentColor == 'rgb(0, 0, 255)')
img = _blueDot;
var bgImage = $(this).css('background-image');
if (bgImage.indexOf(img) < 0)
{
$(this).css('background-image', 'url(' + _imgFolder + img + ')');
if (img == _redDot)
{
$(this).data('toggle', "1");
$(this).data('color', "1");
}
else if (img == _greenDot)
{
$(this).data('toggle', "1");
$(this).data('color', "2");
}
else if (img == _blueDot)
{
$(this).data('toggle', "1");
$(this).data('color', "3");
}
else
{
$(this).data('toggle', "0");
$(this).data('color', "0");
}
}
else
{
$(this).css('background-image', 'url(' + silverPath + ')');
$(this).data('toggle', "0");
$(this).data('color', "0");
}
_mouseDown = 1;
})
.mouseenter(function () {
if (_mouseDown == 1)
{
var silverPath = (_imgFolder + _silverDot);
var img = _redDot;
if (_currentColor == 'rgb(255, 0, 0)')
img = _redDot;
else if (_currentColor == 'rgb(0, 128, 0)')
img = _greenDot;
else if (_currentColor == 'rgb(0, 0, 255)')
img = _blueDot;
var bgImage = $(this).css('background-image');
if (bgImage.indexOf(img) < 0)
{
$(this).css('background-image', 'url(' + _imgFolder + img + ')');
if (img == _redDot)
{
$(this).data('toggle', "1");
$(this).data('color', "1");
}
else if (img == _greenDot)
{
$(this).data('toggle', "1");
$(this).data('color', "2");
}
else if (img == _blueDot)
{
$(this).data('toggle', "1");
$(this).data('color', "3");
}
else
{
$(this).data('toggle', "0");
$(this).data('color', "0");
}
}
else
{
$(this).css('background-image', 'url(' + silverPath + ')');
$(this).data('toggle', "0");
$(this).data('color', "0");
}
}
})
.mouseup(function () {
_mouseDown = 0;
saveDots();
});
/* Choose Color for Dots */
$('.colors').click(function() {
$(this).fadeTo("fast", 0.40)
.css('border', '2px solid black');
_currentColor = $(this).css("background-color");
$('.colors').not(this).fadeTo("fast", 1)
.css('border', '0');
});
/* Default Data and colors */
$(document).ready(function() {
$('.colors#red')
.fadeTo("fast", 0.40)
.css('border', '2px solid black');
$('#r1c1').data('toggle', "0");
$('#r1c2').data('toggle', "0");
$('#r1c3').data('toggle', "0");
$('#r2c1').data('toggle', "0");
$('#r2c2').data('toggle', "0");
$('#r2c3').data('toggle', "0");
$('#r3c1').data('toggle', "0");
$('#r3c2').data('toggle', "0");
$('#r3c3').data('toggle', "0");
$('#r1c1').data('color', "0");
$('#r1c2').data('color', "0");
$('#r1c3').data('color', "0");
$('#r2c1').data('color', "0");
$('#r2c2').data('color', "0");
$('#r2c3').data('color', "0");
$('#r3c1').data('color', "0");
$('#r3c2').data('color', "0");
$('#r3c3').data('color', "0");
});
});
/* Get the Dots Current Status and save through Ajax */
function saveDots() {
var dot1 = $('#r1c1').data('toggle') + '.' + $('#r1c1').data('color');
var dot2 = $('#r1c2').data('toggle') + '.' + $('#r1c2').data('color');
var dot3 = $('#r1c3').data('toggle') + '.' + $('#r1c3').data('color');
var dot4 = $('#r2c1').data('toggle') + '.' + $('#r2c1').data('color');
var dot5 = $('#r2c2').data('toggle') + '.' + $('#r2c2').data('color');
var dot6 = $('#r2c3').data('toggle') + '.' + $('#r2c3').data('color');
var dot7 = $('#r3c1').data('toggle') + '.' + $('#r3c1').data('color');
var dot8 = $('#r3c2').data('toggle') + '.' + $('#r3c2').data('color');
var dot9 = $('#r3c3').data('toggle') + '.' + $('#r3c3').data('color');
/*alert ('saveDots ' + dot1 + ' ' + dot2 + ' ' + dot3 + ' ' + dot4 + ' ' +
dot5 + ' ' + dot6 + ' ' + dot7 + ' ' + dot8 + ' ' + dot9)*/
/* Show Bob Easter Egg */
if ((dot1 == "1.2") && (dot2 == "1.2") && (dot3 == "1.2")
&& (dot4 == "1.2") && (dot5 == "1.3") && (dot6 == "1.3")
&& (dot7 == "1.2") && (dot8 == "1.2") && (dot9 == "1.2"))
sayHiBob();
/* Send Ajax from Here */
}
The Mousedown event starts the selection of the DOTS. At that time, the user can drag the mouse over other buttons using the Mouseenter event or release the mouse triggering the Mouseup event. Whenever the Mouseup event happens we trigger the SaveDots method that will eventually make an AJAX call to the server to save the current state of the DOTS.
Mousedown事件开始选择DOTS.那时,用户可以使用Mouseenter事件将鼠标拖动到其他按钮上,或者释放触发Mouseup事件的鼠标.每当Mouseup事件发生时,我们都会触发SaveDots方法,该方法最终将对服务器进行AJAX调用以保存DOTS的当前状态.
Notice in the JavaScript, I’m saving the DOTS information by using jQuery .data command. This is a nice way to save information but there are some catches with this The data is stored in the jQuery cache so you must retrieve the data by using the .data command and not the .attr command. The reason people tend to make this mistake is because the .data function in JQuery will attempt to convert the variable stored into a type based on the data. In example, “1.4” will be returned as number and not a string where as the storing the data with a the .attr function will always make it a string.
请注意,在JavaScript中,我正在使用jQuery .data命令保存DOTS信息.这是保存信息的好方法,但是有一些问题.数据存储在jQuery缓存中,因此您必须使用.data命令而不是.attr命令来检索数据.人们倾向于犯此错误的原因是因为JQuery中的.data函数将尝试将存储的变量转换为基于数据的类型.例如,” 1.4"将作为数字而不是字符串返回,而使用.attr函数存储数据将始终使其成为字符串.
Publishing To Azure(发布到Azure)
This article is focused around building websites in Azure so there needs to be instructions on how to do this. Attached is a great video which shows the simple process of creating and publishing your website to Azure. Azure really does make it simple to get a website up quickly.
本文的重点是在Azure中构建网站,因此需要有关如何执行此操作的说明.随附的精彩视频演示了创建网站并将其发布到Azure的简单过程. Azure确实确实使快速建立网站变得容易.
<参数名称=“质量” value =“高”/> <参数名称=" wmode" value =“透明”/>
Third Challenge: Using SQL on Azure(第三个挑战:在Azure上使用SQL)
Bringing IT ! - Defining the Domain
带上它! -定义域
Strap in and hold tight because Challenge 3 is where we really start moving in the DOTS article. Previously I’ve talked about domain driven design. The real architecture and strength of the project can now be shown by working from the Database up through the different layers of the project. By demonstrating each layer, the hope is to show that while DOTS is a simple and straight forward idea on the surface, the real intention is to have a nice layout that almost any size website can be grown from and shared.
请紧紧抓住,因为挑战3是我们在DOTS文章中真正开始学习的地方.以前,我已经讨论过域驱动设计.现在,可以通过从数据库开始直到项目的不同层来显示项目的真正架构和实力.通过演示每一层,希望是要表明,尽管DOTS是表面上简单而直接的想法,但真正的目的是要有一个不错的布局,使几乎任何规模的网站都可以从中成长和共享.
In the above diagram, we illustrate a data layer that hides the database but is available to all of our interfaces and APIs. This allows us to centralize our schema definitions so that all are always in synch and available to our communication layer. With this architecture, it is easy for each part of the communication layer to share information as the CRUD services are happening with each other. It is also easy to add new layers for scalability such as a caching layer to the project.
在上图中,我们说明了一个隐藏数据库但可用于所有接口和API的数据层.这使我们可以集中我们的模式定义,以使所有定义始终保持同步并可供我们的通信层使用.通过这种体系结构,当CRUD服务彼此发生时,通信层的每个部分都可以轻松共享信息.为项目增加可伸缩性的新层(例如缓存层)也很容易.
[key point] By doing the design this way, the DOTS piece is really nothing more then a shared group of information among all devices that can talk to our communication layer. The beauty of this, is that what appears to be the centralized theme of the project (the DOTS) is nothing more the a plug-in piece.
[要点]通过这种方式进行设计,DOTS件实际上仅是可以与我们的通信层进行通信的所有设备之间共享的一组信息.这样做的好处是,看起来像项目的集中主题(DOTS)不过是一个插件.
Take a grocery list, a honey-do list, centralized logs, even a group of a social network can all work in this pattern instead of Dots. And even better, the information is now shared among all devices that can hit an API level; smart phones, websites, tablets, servers, and even winform apps.
以杂货店清单,蜜饯清单,集中式日志,甚至是一组社交网络都可以以这种方式工作,而不是点.更好的是,信息现在可以在所有达到API级别的设备之间共享;智能手机,网站,平板电脑,服务器,甚至Winform应用.
This is what makes Azure so Cool! For lack of a better phrase, one hosting service that does it all. In the past, one would need a network of owned or leased servers to accomplish this type of site and then scalability would always haunt the software. Now, we can have it all and “share the cake “ too .
这就是使Azure如此酷的原因!由于缺少更好的用语,因此一项托管服务可以完成所有任务.过去,需要拥有或租用服务器的网络来完成这种类型的站点,然后可伸缩性总是困扰着该软件.现在,我们可以拥有全部,也可以"分担蛋糕".
Azure – Making the Database
Azure –制作数据库
We are going to tackle our model from a Data first design. I first like to make my databases in SQL Server or Express locally so that I can use the design mode of SQL Server.
我们将从数据优先设计解决模型.首先,我希望在SQL Server或Express中本地创建数据库,以便可以使用SQL Server的设计模式.
We need to assume the programmer already knows how to make a database so let’s start by taking our local database that was designed in SQL Server Express 2012 and showing how to get this into Azure. Let’s start by right clicking on the Database and selecting Generate Scripts from the Tasks drop down.
我们需要假设程序员已经知道如何创建数据库,所以让我们从采用SQL Server Express 2012设计的本地数据库开始,并说明如何将其导入Azure.首先,右键单击数据库,然后从"任务"下拉菜单中选择"生成脚本".
Click next until the wizard asks how the scripts should be saved or published. Choose Clipboard but do not click next. Clicked the ‘Advanced’ button first.
单击下一步,直到向导询问如何保存或发布脚本.选择剪贴板,但不要单击下一步.首先单击"高级"按钮.
In the Advanced Scripting Options, make sure you drop down the ‘Script for the database engine type’ and select ‘SQL Azure Database’ as shown.
在"高级脚本选项"中,确保下拉"数据库引擎类型的脚本"并选择" SQL Azure数据库",如图所示.
From here, click ok and follow the rest of the prompts.
在此处,单击确定,然后按照其余提示进行操作.
You now have the script into memory. It’s now time to log into SQL Azure database. The sql Azure server should have been setup in the first part of this article. Go ahead and login to this server through Management Studtio.
现在,您已将该脚本保存到内存中.现在该登录SQL Azure数据库了. sql Azure服务器应该已经在本文的第一部分中进行了设置.继续并通过Management Studtio登录到该服务器.
Open up a new Query window. Paste and run the script. That’s it, you will now have a mirror copy of the database from your local SQL to SQL Azure.
打开一个新的查询窗口.粘贴并运行脚本.就是这样,您现在将拥有从本地SQL到SQL Azure的数据库镜像副本.
Data Layer (资料层)
Repository and Unit of Work Patterns
储存库和工作单元模式
It was decided to use the Repository and Unit of Work Patterns to build our Data Access Layer (DAL). With the use of these patterns, all communications through any framework (e.g. WebAPI, WCF, MVC) will have central access point to the Data. This gives a clean and persistent interaction between the data and all CRUD services to the database. We also have only one place to make changs to our database schema maps instead of changing all projects when there’s a database change.
决定使用存储库和工作单元模式来构建我们的数据访问层(DAL).通过使用这些模式,通过任何框架(例如WebAPI,WCF,MVC)进行的所有通信都将具有对数据的中央访问点.这样就可以在数据与数据库的所有CRUD服务之间进行干净持久的交互.我们也只有一个地方可以更改数据库架构图,而不是在发生数据库更改时更改所有项目.
Linq to Entities is going to be used as the Object-Relational Map (ORM) in our DAL mainly because Microsoft works very nicely with Azure and Entities. There’s no reason to mix up this relationship for this article but note, if there is another favorite ORM, it wouldn’t be hard to implement for this pattern.
Linq to Entities将被用作我们DAL中的Object-Relational Map(ORM),主要是因为Microsoft与Azure和Entities非常兼容.没有理由在本文中混淆这种关系,但是请注意,如果还有另一个喜欢的ORM,则对于这种模式将不难实现.
Here’s a really nice link to better explain and teach the Repository and Unit of Work Patterns.
这是一个非常好的链接,可以更好地解释和教导[存储库和工作单元模式](http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the- ASP.NET MVC应用程序中的存储库和工作单元模式).
Start the Project*
开始项目
Let’s first build a new project in our solution and name it DOTS.Data. You can see where I’m going with the naming convention:
首先让我们在解决方案中构建一个新项目,并将其命名为DOTS.Data.您可以使用命名约定看到我要去的地方:
*DOTS.Web - Web Project DOTS.Data – Data Access Layer Project Later on, I’ll introduce DOTS.WebAPI and DOTS.WCF and so on. *
DOTS.Web-Web项目 DOTS.Data –数据访问层项目 稍后,我将介绍DOTS.WebAPI和DOTS.WCF等.
Building our Repository Pattern
建立我们的存储库模式
Now, let’s build our .NET Entity data model of our database. Right click on our project -> Add New Item -> ADO.NET Entity Data Model -> Generate from Database -> Set Entities Connection to Azure Connection String.*
现在,让我们建立数据库的.NET实体数据模型.右键单击我们的项目->添加新项-> ADO.NET实体数据模型->从数据库生成->将实体连接设置为Azure连接字符串.
Select the Azure connection string or make a new connection to the Azure database. We have DotsConnectionString that I had made previously.*
选择Azure连接字符串或与Azure数据库建立新连接.我们有我之前制作的DotsConnectionString.
In our Data First model, we are going to make the model from an existing Database. We could easily do it the other way however, I usually make my database first. If you know your platform you are programming against like in this case (Azure), then I like to do Data first modeling only because I can design and avoid any limitations of the database engine rather then trying to convert a model into a database. In this project, it’s more of a preference then a right or wrong way of doing it.
在我们的Data First模型中,我们将从现有的数据库中构建模型.我们可以很容易地用另一种方式来做,但是,我通常首先创建数据库.如果您知道您的平台正在像这种情况下那样进行编程(Azure),那么我只喜欢先进行数据建模,因为我可以设计并避免数据库引擎的任何限制,而是尝试将模型转换为数据库.在这个项目中,与其说是对,不如说是做事的首选.
Choose all the Tables so Maps can be made from them all.
Now a model diagrm should be shown as in the one below.
Now time to make the Interface for our new Repository. Add New Item -> Interface -> Name it IRepository.cs
The interface is what is going to guarantee the rules that our repository is going to have. Think of it as a contract to anyone that is working with the repository to make sure we are creating things write. Here’s the code we have for this:*
选择所有表格,以便可以从它们全部制作地图.
现在,应显示模型诊断图,如下所示.
现在是时候为我们的新存储库创建接口了.添加新项->接口->命名为IRepository.cs
该接口将保证我们的存储库将具有的规则.可以将它视为与任何正在使用存储库的人员的合同,以确保我们创建的东西是可写的.这是我们的代码:
using System.Linq;
namespace DOTS.Data
{
public interface IRepository<t> where T : class
{
IQueryable GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(int id);
}
}
Ok, let’s create the actual Repository that implements the interface from above. Add New Item -> Class -> Repository.cs
好的,让我们创建一个实际的存储库,从上面实现该接口.添加新项目->类-> Repository.cs
- *
And here’s what my repository looks like so far:
到目前为止,这是我的存储库外观:
using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
namespace DOTS.Data
{
public class Repository<t> : IRepository<t> where T : class
{
protected DotsEntities DbContext { get; set; }
protected DbSet<t> DbSet { get; set; }
public Repository(DotsEntities dbContext)
{
if (dbContext == null) throw new NullReferenceException("dbContext");
DbContext = dbContext;
DbSet = dbContext.Set<t>();
}
#region Implementation of IRepository<t>
public IQueryable GetAll()
{
return DbSet;
}
//public T GetById(int id)
//{
// return DbSet.Find(id);
//}
public T GetById(int id)
{
var someEntity = DbSet.Find(id);
return someEntity;
}
public void Add(T entity)
{
DbSet.Add(entity);
}
public void Update(T entity)
{
var entry = DbContext.Entry(entity);
DbSet.Attach(entity);
entry.State = EntityState.Modified;
}
public void Delete(T entity)
{
var entry = DbContext.Entry(entity);
DbSet.Attach(entity);
entry.State = EntityState.Deleted;
}
public void Delete(int id)
{
var entity = GetById(id);
if (entity == null) return;
Delete(entity);
}
#endregion
}
}
There we go; now we can perform some CRUD operations to the database but our DAL is not done yet. We still have to make the Unit of Work. The Unit of Work will let us actually write the Entities out to the Database in a operational manner.
Building the Unit of Work Pattern
Finally, we get to build the Unit of Work Pattern. If the Repository is to store models for related tables, think of this as the object model of the Database that holds the Repositories.
Add New Item -> Class -> Name it Database.cs
我们去了;现在我们可以对数据库执行一些CRUD操作,但DAL尚未完成.我们仍然必须制定工作单元.工作单元将使我们能够以可操作的方式将实体实际写出到数据库中.
建立工作单元模式
最后,我们建立了工作单元模式.如果存储库要存储相关表的模型,则可以将其视为保存该存储库的数据库的对象模型.
添加新项目->类->命名为Database.cs
* Here’s the code that’s in the Unit of work. Notice it’s mainly it just gives us access to the repositories under a centralized class that we can appreciate the meaning of.*
这是工作单元中的代码.注意,主要是它使我们可以访问集中式类下的存储库,我们可以理解其中的含义.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DOTS.Data
{
public class Database
{
private readonly DotsEntities _databaseContext = new DotsEntities();
public IRepository<map> Map
{
get { return new Repository<map>(_databaseContext); }
}
public IRepository<mapvalue> MapValue
{
get { return new Repository<mapvalue>(_databaseContext); }
}
public void Save()
{
_databaseContext.SaveChanges();
}
}
}
With the Unit of Work implementation, we can do CRUD operations easily. Let’s look at how something like this would look. Here’s some code that I used to test the Unit of Work. You can see how easy and intuitive it is to work with this model.
使用工作单元实施,我们可以轻松进行CRUD操作.让我们看看这样的样子.这是我用来测试工作单元的一些代码.您会看到使用此模型是多么容易和直观.
DOTS.Data.Database database = new Database();
DOTS.Data.Map newMap = new Map();
newMap.name = "TEST";
newMap.writeQuestion = "What is my Dogs Name";
newMap.writeAnswer = "Fido";
newMap.created = DateTime.Now;
database.Map.Add(newMap);
database.Save();
Data Access Layer Conclusion
This completes our Data Access Layer for now. Now we can jump into the Communication Layer. I did get a great start on building the Communication Layer so in the source, there is a working WebAPI project but I’m going to stray a little in the next challenge and link up the communication layer. I’ll also hook up a WinForms app to our API which will show how Azure Virtual Machines can be a great place for testing Windows Apps.
The project is starting to come together and I’m learning a lot about writing these types of articles. I hope you enjoy the read and seeing it come together as well.*
数据访问层结论
至此,我们的数据访问层已完成.现在我们可以跳入通信层.我确实在构建通信层方面取得了良好的开端,因此在源代码中,有一个正在运行的WebAPI项目,但是我将在下一个挑战中稍加偏离,并连接通信层.我还将将WinForms应用程序连接到我们的API,该应用程序将展示Azure虚拟机如何成为测试Windows Apps的理想场所.
该项目开始整合在一起,我正在学习有关编写这类文章的很多知识.我希望您喜欢阅读并看到它也融为一体.
Fourth Challenge: Virtual Machines(第四项挑战:虚拟机)
Communication Layer
通讯层
- Web API and Ajax Coming Soon.. ClosingDOTS is going to present many unique challenges for me. This project will be the first time I branch out of my database roots and attempt to also write a communication method or protocol. In doing this, I’m hoping to gain and pass a long some great knowledge of modern techniques of building websites and interacting with the cloud.I also would like to thank my co-workers for their help in discussing and helping me come up with an idea for entering this contest.(Web API和Ajax即将推出..ClosingDOTS将为我带来许多独特的挑战.该项目将是我第一次脱离数据库根目录并尝试编写一种通信方法或协议.在此过程中,我希望获得并传递有关建立网站和与云进行交互的现代技术的长期知识,也要感谢我的同事们在讨论和帮助我提出建议方面的帮助参加比赛的想法.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# Javascript SQL .NET Intermediate MVC jQuery AppFabric Azure cloud .NET4.5 新闻 翻译