Anping 中文

New tab or iframe

A new tab gives the desktop the whole window. An iframe, a frame inside your own page, keeps it in your page.

New tabIframe
Setting on the Anping servernoneyour site's address in Oturl:FrameAncestors
Win, Alt+Tabfull screen (Chrome, Edge) or KeysKeys (a frame can't capture these keys)
Ctrl+Alt+DelKeysKeys
Reloadreconnects for a while (the reconnect window)reconnects if the browser remembers the link (below)

New tab

Open the tab right when the user clicks, then ask your server for the link. Browsers block new windows that open later (popup blockers).

button.addEventListener('click', async () => {
  const tab = window.open('', '_blank')   // during the click
  if (tab) tab.opener = null
  const response = await fetch('/api/anping-link', { method: 'POST' })
  const { url } = await response.json()   // your server asks Anping
  if (tab) tab.location.replace(url)
})
Your page itself runs in a restricted frame (sandbox)?

That frame needs allow-popups and allow-popups-to-escape-sandbox in its sandbox attribute, or the new tab is blocked or stays sandboxed.

Iframe

<iframe src="https://anping.example.com/oturl.html?key=...&pass=..."
        title="Remote desktop"
        allow="fullscreen; clipboard-read; clipboard-write; autoplay"
        referrerpolicy="no-referrer"
        style="width: 100%; height: 80vh; border: 0"></iframe>
In allowWhy you need it
fullscreenThe toolbar's Full screen button.
clipboard-read, clipboard-writeCopy and paste work by themselves where the browser allows it; otherwise users use the Clipboard panel.
autoplaySound starts after a click in your page, not only in the frame.
MoreWithout it the toolbar shows Enable sound until a click or key press in the frame.
referrerpolicy="no-referrer"The link's secret parts (key and pass) are never passed on to other sites.

With resolution=fittobrowser the remote screen follows the frame's size.

Allow your page

Only the link page (/oturl.html) can be shown in a frame, and only on the sites you list. Write each site as https:// and its host name (and port), without a path, or 'self'.

Technical detail

Anping sends the list as Content-Security-Policy: frame-ancestors.

Oturl__FrameAncestors__0=https://app.example.com
Oturl__FrameAncestors__1=https://portal.example.com

Reloading inside a frame

The browser remembers the link with a small cookie. In a frame on https, each site that shows Anping gets its own (technical detail: SameSite=None; Secure; Partitioned).

BrowserA reload of your page
Chrome, Edge (114 and later)Reconnects (tested).
FirefoxShould reconnect; not fully tested yet.
SafariBlocks cookies from other sites, so most likely shows the used message.
Plain http (development)Works only when your page is on the same site (technical detail: SameSite=Strict).
When the cookie is blocked; behind a load balancer

Messages to your page

The page in the frame tells your page what happens (with postMessage). Only the sites listed in Oturl:FrameAncestors hear it.

Embedding events: the link page posts connected, reconnecting, disconnected, ended or link_invalid as the session changes; the numbers match the list under the drawing. link opens connected reconnecting disconnected ended link_invalid 1 2 3 4 5 6 7 8 9 Embedding events: the link page posts connected, reconnecting, disconnected, ended or link_invalid as the session changes; the numbers match the list under the drawing. link opens connected reconnecting disconnected ended link_invalid 1 2 3 4 5 6 7 8 9
Each arrow sends the event it points to.
  1. Desktop shows, also after each reconnect
  2. Link used, expired or unknown
  3. Connection dropped: the page retries
  4. Back in time
  5. Not back within a minute (a final error: ended)
  6. Disconnect, remote ended or an error
  7. User pressed Reconnect
  8. Reconnect window over
  9. End, idle or time limit, restart, final error: a new link is needed
window.addEventListener('message', (e) => {
  if (e.origin !== 'https://anping.example.com' || e.data?.source !== 'anping' || e.data.v !== 1) return
  // e.data.type: connected | reconnecting | disconnected | ended | link_invalid
})

Each message looks like {source: 'anping', v: 1, type, link, code?, until?}. link is the link's code: not secret, the same as in the connection log, and null until Anping has given it one. v is the version: it changes only if a field changes meaning or goes away. In the table, type is what happened, code why, and until the time until which the page keeps trying or Reconnect still works.

typecodeuntil
connectednonenone
reconnectingconnection_lost or another short-lived errorwhen it stops trying
disconnectedclosed (Disconnect, or the remote ended) or an error codeend of the reconnect window
endedsession_ended (the user chose End), idle_timeout, max_duration, server_restart, another error code, or the disconnected code once its window is overnone
link_invalidnonenone

Sound and autoplay

Browsers allow sound only after the user interacts, so a link's sound (soundenabled=true) starts at the first click or key press. Until then the toolbar shows Enable sound, then Mute or Unmute. In an iframe, add autoplay to allow.

More

Sound that arrives before that is dropped, so nothing plays all at once later.