Skip to content
Yichao Yu edited this page Feb 27, 2021 · 16 revisions

This is a general overview of the design of the frontend.

Goals

We run the experiments from the control computer which talks to various backends mainly via network communication. This is very flexible but can be a little tricky when doing simple tasks like changing a single value. OTOH, the old web frontend can be access fairly easily from different devices but requires the device to be on the internal network and also only works for the FPGA backend. The goal for the new web frontend is therefore to combine the advantage of the two approaches and to make it easier to control all the devices from inside and also outside the lab. The requirements for the new frontends includes,

  1. Web based and mobile aware

    This should make it easy for people working in the lab to control all the channels from their phones.

  2. Accessible from outside the lab

    This should make it much more convenient to check and change values from outside the lab. For security reason, accessing the frontend from outside the lab will require logging in.

  3. Works for more than just the FPGA backend

    We should be able to connect to different backends using a similar protocol with how the main control computer talks to each backends. Some changes/additions to the protocol might be necessary in order to display the current status of each backends. This also means that this web server doesn't have to and shouldn't be running on the FPGA board. Instead, we can run it on a separate linux server in the lab.

  4. Allow setting value in an overwrite and non-overwrite way more consistently

    Currently the DDS channels can only be changed from the web interface without overwrite and the TTL channels can only be changed by overwriting the values. (Overwrite means it'll ignore the values from the sequence). We often find it useful if we could overwrite a DDS channel or set a TTL channel without overwriting it. This would both be a frontend and a backend feature (i.e. the backend protocol may need some upgrade to support this).

  5. Allow connecting to devices for more than one experiments

    Out of necessity, 1.5 and 1.0 uses the same public address so it'll be more convinient if we could use the same website to control both experiments.

  6. Custom user settings

    From the previous requirement, each user should be able to customize their default experiment/pages etc.

  7. More customizable UI

    When doing certain tasks, it is often necessary to change a few channels repeatedly. These channel may not be of the same type and they may not be close to each other in the numbering. It'll be more convenient if the user can construct a custom UI so that only the necessary channels for a certain task are shown. This customized UI should be savable and could be both user specific or being shared between users/groups.

Tool selection

There are waaay too many web frameworks to choose from and it's really hard to decide which one works the best without trying all of them. Therefore, the choice of the framework here may not be the best one but I'll at least list the reason why it might be "good enough" and how it compared to other ones I've used before. In additional to the requirements on the features we want to support for the user, there are a few more technical requirements.

  1. Easy server-client communication.

    The main purpose of this web interface is to control and check the status of different equipment so it is critical that we can pass data between the server and the client easily (low overhead and easy to program). I would also like to be able to use websocket when available.

  2. Combining server logic and client logic.

    We need to keep some state on both the server side (equipment related) and client side (UI related) so it'll be nice if the framework supports both equally well.

  3. Authentication support.

    Necessary for accessing the server from outside the lab.

  4. C/C++ extension support.

    We have a few C++ functions in libnacs that will be useful for the web frontend (e.g. constant values and sequence parser). Although we could rewrite them in whichever language we use, it would be much better if we could simply call the C++ code.

  5. Support zmq.

    This is how we'll talk to the backends.

Most popular server-side web framework should satisfy the requirements above fine (client-side only framework won't work due to the server-client communication requirement). I have previously tested a C++ framework Wt. It works well for most of the requirements but fail a little short on supporting client side logic since it tracks most of the states on the server side and doing tricks to manage things on the client side isn't entirely trivial. The basic tool I end up using is nodejs mostly because we have other projects using node in the lab (though they are using very different packages). On top of that, we are using Next.js to allow writing the server and client side code both in js and in a very similar manner. This is the biggest advantage of writing the server side code in JS.

For the build system, we are using cmake just like all of our other projects. Although it doesn't do much to manage the nodejs project, we can still integrate it with the nodejs/npm fairly well and we'll use it to primarily handle the compilation of our C++ extension and also the installation and deployment as a package.

Directory structure

  • cmake/

    This is the cmake modules and related files to allow us managing the nodejs/npm project with cmake.

  • addon/

    This is where our C++ extension locates. Unlike most other directly containing js files that can be run directly, the compilation result will be located in the binary directory of the cmake working directory. We use cmake custom command to set the path to the binary directory for the test server to find thid directory.

  • conf/

    An example config file for the server. The deployed server will most likely have a config file with different content/paths.

  • public/

    All the static content used by the client side. Files in this directly will be served directly by the server. Do no put any sensitive information in this directory.

  • tests/

    Everything that are only used for development and testing. Including unit tests for certain components as well as a test server.

  • components/ and pages/

    These are the standard Next.js directories for components and pages. See the Next.js document for more information. This code will be used by both the client and the server.

  • lib/

    This contains code that can run on both the client and the server (also includes some library functions that run only on the server or client), i.e. similar to components/ and pages/ although these code do not have any special meaning to Next.js and it may or may not be compiled by Next.js/webpack depending on who loads the code. Certain files in this directory, e.g. api.js and crypto.js contains server/client dispatch to allow the server and the client to use different implementations automatically.

  • server/

    This contains code that should only be run on the server. This includes code that only makes sense on the server, like the server dispatch logic itself, logics that must be done on the server, like login/authentication, and code that can only be run on the server, like code that talks to the C++ extension or access the database. This is also where the server communicates with different backends via zmq.

  • apis/

    This is also server-only code but unlike server/ these are API functions for the client and will be automatically discovered by the server. Due to the nature of the Next.js (which has both server and client side render), these functions may be called both from the client or the server side. The lib/api.js module makes sure that the functions in this directory are used directly without any network roundtrip when called from the server side whereas it'll send a network requires to the server to call these functions if the api function is called on the client side.

Subsystems

WIP document

  • Admin

    apis/all_users.js apis/set_flags.js pages/admin.js

  • User Profile

    apis/change_password.js apis/user.js components/ChangePassword.js pages/change-password.js pages/profile.js

  • Email Token

    apis/check_token.js apis/invite.js apis/register.js apis/request_approval.js apis/reset_password.js pages/lost-password.js pages/register.js pages/verify.js

  • User Session/Login

    apis/login.js apis/logout.js components/CheckAnonymous.js components/CheckLogin.js components/Login.js pages/index.js pages/login.js server/user.js server/user_session.js

  • Global Context

    components/Global.js

  • Misc component

    components/RedirectIn.js

  • Page structure

    components/NotifyMenu.js components/Wrapper.js pages/_app.js pages/_document.js

  • Server

    server/server.js index.js next.config.js

  • Zynq Backend

    server/zynq.js

See the linked page for the tests that requires interaction.

Clone this wiki locally