[译]优化Web的Push框架:Websocket,SSL,Json,AngularJs和MySQL的使用
By robot-v1.0
本文链接 https://www.kyfws.com/applications/optimizing-push-framework-for-the-web-use-of-webso-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 12 分钟阅读 - 5885 个词 阅读量 0[译]优化Web的Push框架:Websocket,SSL,Json,AngularJs和MySQL的使用
原文地址:https://www.codeproject.com/Articles/842131/Optimizing-Push-Framework-for-the-Web-Use-of-Webso
原文作者:Ahmed Charfeddine
译文由本站 robot-v1.0 翻译
前言
Websocket, SSL, Json, MySQL are all combined together with Push Framework to produce a C++ server that interacts with an Angularjs web front-end. The application shows the ease of implementing CRUD.
Websocket,SSL,Json,MySQL都与Push Framework结合在一起,以生成与Angularjs Web前端进行交互的C ++服务器.该应用程序显示了实现CRUD的简便性.
介绍(Introduction)
今天,将C ++用作Web应用程序的后端听起来像是一种奇怪的处理方式.在本文中,我将向您展示多种技术组合,这些技术会让您另类思考.通过演示一些常见方案的实现,读者可以判断将其扩展到实际案例中的复杂性.(Using C++ as backend to a Web application may sound like a strange way to do things today. In this article I will show you a combination of technologies that will make you think otherwise. By demo-ing the implementation of some of common scenarios, the reader can judge the complexity of extending this to a real world case application.)
目标(Goal)
让我们在这里定义我们的目标.首先我们问:开发人员面临的常见实施场景是什么?(Let’s define our goal here. First we ask: what are the common scenarios that developers face to implement ?)
答案一定很简单:(The answer must be easy:)
- 必须定义并保留项目类型T1,T2,..的列表.(A list of item types T1, T2, .. have to be defined and persisted.)
- 给定类型T,用户希望前端显示可用项目列表(Given a type T, user wants the front end to display a list of available items)
- 前端必须提供一种显示表单的方法,该表单创建或编辑给定类型T的实例(The front end must provide a way to display a form that creates or edits an instance of a given type T)
- 给定一个UI,我们需要一种让用户轻松查找给定类型T项的方法.这种情况的常见情况是,类型T1与类型T2具有外部关系时,这意味着对对象T2的实例进行编辑T1涉及选择T2的实例.(Given a UI, we need a way for the user to easily lookup for an item of a given type T. A common case of this is when a type T1 has an external relationship with a type T2, meaning that the editing of an instance of T1, involves the selection of an instance of T2.) 我相信,即使有人不同意这个答案,他们仍然会同意,这些足够重要的场景,使他们能够体会到任何简单且可扩展的实施方式.因此,让我们的目标定义为证明易于实现这些方案.(Even if some would disagree on this answer, I believe, they would still agree that these are enough important scenarios for them to appreciate any easy and extensible way of their implementation. So let our goal be defined as proving it is easy to implement these scenarios.)
AngularJs(AngularJs)
今天有太多的设计和操作系统.使用HTML5和Javascript的Web应用程序是构建跨平台前端的最佳答案.随着像AngularJs这样的新库的出现,JavaScript开发确实开始引起人们的注意.这里开发的演示应用程序的前端部分将使用AngularJs构建的控件进行编码.(There are too many devises and operating systems today. Web applications using HTML5 and Javascript are being the best answer to building a cross plateform front end. With the advent of new libraries like AngularJs, Javascript development is really starting to make sens. The demo-application that is developed here, will have its front end part coded using controls built using AngularJs.)
Websocket(Websocket)
Websocket是当今大多数浏览器实现的基于TCP的协议.它允许网页打开与兼容服务器的全双工TCP连接.重要的是要注意,这是一个比Ajax更强大的想法.(Websocket is a protocol on top of TCP that most browsers implement nowadays. It allows a Web page to open a full duplex TCP connection with a compliant server. It is important to note that this is a much more powerful idea than Ajax.)
AngularJs + Websocket =?(AngularJs + Websocket = ?)
两种技术的结合使得使用大多数交互逻辑在客户端执行创建桌面级UI以及流向实时服务器的所有数据和命令都与Web服务器无关的情况成为可能.已访问该应用程序.在这里的演示中,Web服务器仅用于将资产从应用程序机器下载到最终用户设备.(The combination of these two technologies makes it possible to create a desktop-grade UI , using most of interaction logic executing client-side, and all the data and commands flowing to a real time server that has nothing to do with the Web server through which application was accessed. In our demo here, the Web server merely servs to the download of assets from the application machine to the end user devise.)
推送框架(Push Framework)
推框架将用于通过接收命令并发送回数据来构建与前端部分进行交互的服务器.(Push Framework will be used to build the server that will interact with the Front end part, by receiving commands and sending back data.)
第3版通过以下方式优化了设计:(Version 3 has optimized the design in a way it is possible to:)
-
插入任何协议实现. (将协议逻辑分离到一个单独的抽象库:协议基础)(Plug any protocol implementation. (Separation of protocol logic to a separate abstract library: protocol foundation))
-
垂直和水平插入任意数量的协议:(Plug any number of protocols, vertically and horizontally:)
- Push Framework服务器可以通过不同的端口进行侦听.可以为每个端口指定不同的协议栈.那是水平方向.(A Push Framework- server can listen through different ports. A different stack of protocols can be specified for each port. That is horizontal direction.)
- 对于每个端口,我们可以将不同的协议插入为彼此之上的层:即垂直方向.(For each port, we can plug different protocols as layers on top of each others: that is vertical direction.)
-
不管协议选择如何,都可以插入任何类型的序列化方法.(Plug any type of serialization method regardless of protocol choice.)
构建Push Framework协议(Building protocols for Push Framework)
在构建服务器应用程序之前,我们需要解决3个问题.首先,由于Javscript将打开Websocket连接,因此我们需要服务器能够解码该协议.因此,我们需要Websocket的协议层实现.其次,许多人将需要通过TLS进行安全连接.因此,我们需要TLS的层实现.第三,由于Json是Javascript的默认集成序列化方法,因此我们需要服务器期望以这种方式构造数据.因此,我们需要一个Json序列化实现.(Before we build the server application, we need to solve 3 problems. First, since Javscript will open up a Websocket connection, we need the server to be able to decode this protocol. We therefore need a protocol layer implementation of Websocket. Second, many will need a secured connection by means of TLS. We therefore need to have a layer implementation of TLS. Third, since Json is the default, integrated serialization method for Javascript, we need the server to expect data structured in that way. Therefore we need a a Json serialization implementation.)
的MySQL(MySQL)
该服务器是一个不错的选择,特别是对于那些希望从事新项目并且不想冒险购买昂贵的Oracle或SQL Server许可证的人而言.我们将使用MySQL ++库轻松与服务器通信.该库还具有用于连接池的实现,这对于提高应用程序速度非常有用.(This server is a good choice especially for those who want to embark into a new project and dont to risk money in an expensive Oracle or SQL Server license. We will use MySQL++ library to easily communicate with the server. This library also has implementation for connection pools which is great for application speed.)
DAO,DTO和服务器端分页(DAO, DTO, and server-side pagination)
MySQL ++库极大地降低了与MySQL默认API交互以发送SQL查询并在查询执行后检索数据的复杂性.但是,今天有许多人习惯了持久性框架,该框架可以自动完成与DBMS交互的所有工作.由于C ++中没有此类框架,因此本文使用代码生成的方法:(MySQL++ library helps a lot reduce the complexity of interacting with MySQL default API to send SQL queries and retrieve data after query execution. However many people today got used to persistance framework that do all the job of interacting with the DBMS automatically. Since there is no such frameworks in C++, this article uses the approach of code generation:)
-
使用提供的生成器,您可以连接到现有的MySQL数据库并选择一个SQL表.(Using a generator that is supplied, you connect to an existing MySQL database and select a SQL Table.)
-
生成器将创建包含代表您的DAO的C ++类的.h和.cpp文件.假设您有一个名为"人"的表.您将获得一个名为Person的C ++类,该类是从名为BaseDAO的基础对象派生的.该类包含属性形式的所有表字段.它还包含getter和setter,并为基类中的以下成员实现所有虚拟逻辑:(The generator creates .h and .cpp files containing C++ class that represents your DAO. Say, you have a table called Person. You get a C++ class called Person deriving from a base object called BaseDAO. The class contains all the table fields in form of attributes. It also contains getters and setters and implement all virtual logic for the following members in the base class to be possible:)
- bool SaveChanges();(bool SaveChanges();)
- bool GetFromDatabase(int _id);(bool GetFromDatabase(int _id);)
- void SerializeToJson(Json :: Value&jsonObjVal);(void SerializeToJson(Json::Value& jsonObjVal);)
- 无效UpdateFromJson(Json :: Value&jsonObjVal);(void UpdateFromJson(Json::Value& jsonObjVal);)
- bool deleteFromDB(int id);(bool deleteFromDB(int id);)
-
C ++类具有将其自身转换为可以发送到客户端的DTO的所有逻辑.(The C++ class has all logic to turn itself into a DTO that can be sent to the client.)
-
辅助视图类使您可以轻松访问SQL视图.这用于返回DTO列表,这些DTO可以为客户端网格或查找控件提供反馈,并且所有分页逻辑都在服务器端执行.(A helper View class allows you to easily access SQL views. This is used to return a list of DTOs that can feed client grids or look-up controls with all paging logic executing server-side.)
让我们先运行应用程序(Let’s run the application first)
让我们确保您能够获得应用程序代码,对其进行编译并成功运行.(Let us make sure you are able to get the application code, compile it and run it successfully.)
- 解压包装(Unzip the package)
- (可选)将WebApp目录部署到Web服务器.它包含您可以导航到或在本地打开的Index.html.(Optionally deploy the WebApp directory to a Webserver. This contains the Index.html that you can navigate to, or openup locally.)
- 使用Visual Studio 2012打开Demo.sln解决方案文件(Demo.sln在Example目录中找到)(Open Demo.sln solution file using Visual Studio 2012 (Demo.sln is found in Example directory))
- 编译调试解决方案(Compile the solution for Debug)
- 成功编译后,“输出"目录将包含二进制文件.(“Output” directory will contain the binaries after successful compilation.)
- 现在已经构建了服务器应用程序,在启动它之前,我们需要设置一个数据库.(Now that the server application is built, before it can be started we need to setup a database.)
- 下载并设置(Download and setup) 来自互联网的MySQL服务器(MySQL server from Internet) . (可选)下载和设置(. Optionally download and setup) MySQL工作台(MySQL Workbench) 轻松管理服务器.(to easily manage the server.)
- 目录数据库包含一个sql脚本.使用脚本来创建数据库以及视图和表,并用数据填充它们.(The directory Database contains a sql script. Use the script to create the database along with views and tables and populate them with data.)
- 在运行DemoAngularJsServer.exe之前,请修改DemoAngularJsServer.ini以反映特定于您的环境的数据库设置.(Before running DemoAngularJsServer.exe, modify DemoAngularJsServer.ini to reflect the database settings specific to your environent.)
- 运行服务器.它将开始侦听端口81.(Run the server. It will start listening on port 81.)
- 打开WebApp起始页.您应该看到一个项目网格.(Open the WebApp starting page. You should see a Grid of items.)
- 在网格中选择一行,然后单击"编辑”.使用"表单"编辑项的属性,然后单击"保存".(Select a row in the grid and click Edit. Use the Form to edit property of the item and hit Save.)
解释发生了什么(Explaining what happens)
- 打开页面时,AngularJs控制器(HeaderCtrl)请求与服务器的Websocket连接.(When the page is opened, an AngularJs controller (HeaderCtrl) requests a Websocket connection with the server.)
- 另外两个控制器EmployeeListCtrl和CompanyListCtrl将进行调用以检索项目列表(员工和公司)并将其显示在其网格中.(Two other controllers EmployeeListCtrl and CompanyListCtrl will make calls to retrieve list of items (employees and companies) and show them in their grids.)
- 当初始化网格,排序标题或单击网格页面时,将执行Javascript回调,其中提供所有选项,这些选项允许服务器访问SQL视图并返回有限的行集.(When a grid is initialized, or a header is sorted, or a grid page is clicked, a Javascript callback is made, supplying all options that allow server to access a SQL view and return a limited set of rows.)
- 单击"编辑选择"时,网格行对象的ID将发送到服务器以获取对象的完整详细信息(When ‘Edit Selection’ is clicked, the Id of the object of the grid row is sent to the server to get full details of the object)
- 收到对象的全部详细信息后,它们将以Web形式显示.(When the full details of the object are received, they are show in a web form.)
- 更改fom,将更改绑定到它的Javascript对象.(Changing the fom, will change the Javascript object bound to it.)
- 单击"保存",会将修改后的对象发送到C ++服务器,该服务器准备DAO,并使用传入的Json对象中发现的更改对其进行更新,并调用SaveToDatabase,其中包含生成的代码,该代码负责调用数据库,执行UPDATE语句.(Clicking Save, will send the modified object to the C++ server, which prepares a DAO, updates it with changes found in the incoming Json object and calls SaveToDatabase which contains generated code that takes care of calling the database, executing an UPDATE statement.)
支持新类型的复杂性.(The complexity of supporting new types.)
添加新类型时,只需执行以下步骤:(When a new type is added, only the following steps need be done:)
-
手动为新类型创建一个MySQL表.(Manually create a MySQL table for the new type.)
-
执行MySQL.Codegen.exe,输入数据库信息,表名,然后单击(Execute MySQL.Codegen.exe, input the database information, the table name, and click)生成(Generate).(.)
-
将生成的.h和.cpp类文件移动到C ++服务器项目中.将它们添加到项目文件列表.(Move the generated .h and .cpp class files to the C++ server project. Add them to list of project files.)
-
修改AngularClient ::(Modify AngularClient::)getDAOByName(getDAOByName)以便可以支持新类型.(so that it can support the new type.)
-
如果需要显示项目列表或在客户端进行查找,请为该类型创建一个SQL视图.如果类型与其他类型具有外部关系,则可以通过使用来自外部类型的列来丰富列来改善视图.例如,每个员工行都有一个companyId,但是在显示员工列表时,我们也会显示公司名称.(Create a SQL view for the type if you need to show a list of items or do lookup in client side. If the type has external relationship with other types, the view may be improved by enriching the columns with columns from the external types. For example, each employee row has a companyId, but when displaying a list of employees we also show the company name.)
-
在此步骤中,这实际上是服务器端所需的全部内容.(At this step, that is really all what is needed for server-side.)在步骤4中只需手动编写两行编码(Only two lines of coding to be manually written in Step 4)!(!)
-
转到客户端,添加一个新的所需视图以及控制器,并将它们与应用程序链接(主要在app.js中)(Going to the client-side, add a new desired view plus controller, and link them with the application (mainly in app.js))
-
要添加与现有类型(公司和员工)相似的行为,可以复制文件.真正发生的所有变化如下:(To add similar behavior to what we have with existing types (Company and Employee), you can copy the files. All what really changes is the following:)
- 为了使网格正常工作,当它调用WebsocketService.getView时,为其提供适当的(For the grid to work, when it makes a call to WebsocketService.getView, supply it with the proper)SQL视图名称(SQL view name)您创建的!(your created!)
- 为了使表单正常工作,请将您的控件绑定到完全相同的表字段名称,然后在控制器调用WebsocketService.getItem或WebsocketService.deleteItem的位置进行evry,请确保(For the form to work, bound your controls to exact same table fields names, then evrywhere the controller calls WebsocketService.getItem or WebsocketService.deleteItem, make sure to)提供正确的类型名称(supply the proper type name)!(!)
-
如果类型具有外部关系,则需要允许用户在编辑表单时设置这些关系.为此,请查看"员工表单"的现有代码:(If the type has external relationships, you need to allow the user to set those relationships when editing a form. For that, look at the existing code for Employee Form: all is needed is)
- 为了进行编辑,请将关系字段绑定到预输入控件(For editing, bind the relationship field to a typeahead control)
- 要显示由在已编辑/显示的对象中找到的Id表示的实体的名称,请在控制器启动时进行查找以检索外部对象,并使用适当的字段将预先输入的显示文本初始化.(To display the name of the entity represented by the Id found in the edited/displayed object, do a lookup at start of controller to retrieve the external object and intialize the typeahead display text with the proper field.)
从这些步骤中,可以判断实现所有这些标准方案需要付出多少努力.(From these steps, it is possible to judge how much effort is needed to implement all these standard scenarios.)
历史(History)
这是本文的初始版本.(This is currently the intial version of this article.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# Javascript SQL HTML C++ VS2013 AngularJs SSL WebSockets JSON 新闻 翻译