Merge pull request #85 from tauri-apps/websocket
chore: Add tauri-plugin-websocket historypull/87/head
@ -1 +1 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
vite.config.js.timestamp-*
|
||||||
|
vite.config.ts.timestamp-*
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "svelte-app",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"tauri": "tauri"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sveltejs/adapter-auto": "^1.0.0",
|
||||||
|
"@sveltejs/kit": "^1.0.0",
|
||||||
|
"svelte": "^3.54.0",
|
||||||
|
"svelte-check": "^2.9.2",
|
||||||
|
"tslib": "^2.4.1",
|
||||||
|
"typescript": "^4.9.3",
|
||||||
|
"vite": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tauri-apps/cli": "^1.0.0",
|
||||||
|
"tauri-plugin-websocket-api": "link:../../"
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
WixTools
|
||||||
|
|
||||||
|
# These are backup files generated by rustfmt
|
||||||
|
**/*.rs.bk
|
@ -0,0 +1,23 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "app"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A Tauri App"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
tauri = { version = "1", features = [] }
|
||||||
|
tokio = { version = "1.11", features = ["net"] }
|
||||||
|
futures-util = "0.3"
|
||||||
|
tauri-plugin-websocket = { path = "../../../" }
|
||||||
|
tokio-tungstenite = "0.15"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { version = "1", features = [] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "custom-protocol" ]
|
||||||
|
custom-protocol = [ "tauri/custom-protocol" ]
|
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 88 KiB |
@ -0,0 +1,13 @@
|
|||||||
|
max_width = 100
|
||||||
|
hard_tabs = false
|
||||||
|
tab_spaces = 2
|
||||||
|
newline_style = "Auto"
|
||||||
|
use_small_heuristics = "Default"
|
||||||
|
reorder_imports = true
|
||||||
|
reorder_modules = true
|
||||||
|
remove_nested_parens = true
|
||||||
|
edition = "2018"
|
||||||
|
merge_derives = true
|
||||||
|
use_try_shorthand = false
|
||||||
|
use_field_init_shorthand = false
|
||||||
|
force_explicit_abi = true
|
@ -0,0 +1,38 @@
|
|||||||
|
#![cfg_attr(
|
||||||
|
all(not(debug_assertions), target_os = "windows"),
|
||||||
|
windows_subsystem = "windows"
|
||||||
|
)]
|
||||||
|
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
|
||||||
|
async fn start_server() {
|
||||||
|
let addr = "127.0.0.1:8080".to_string();
|
||||||
|
|
||||||
|
// Create the event loop and TCP listener we'll accept connections on.
|
||||||
|
let try_socket = TcpListener::bind(&addr).await;
|
||||||
|
let listener = try_socket.expect("Failed to bind");
|
||||||
|
|
||||||
|
while let Ok((stream, _)) = listener.accept().await {
|
||||||
|
tokio::spawn(accept_connection(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn accept_connection(stream: TcpStream) {
|
||||||
|
let ws_stream = tokio_tungstenite::accept_async(stream)
|
||||||
|
.await
|
||||||
|
.expect("Error during the websocket handshake occurred");
|
||||||
|
|
||||||
|
let (write, read) = ws_stream.split();
|
||||||
|
if let Err(e) = read.forward(write).await {
|
||||||
|
eprintln!("Error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
tauri::async_runtime::spawn(start_server());
|
||||||
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_websocket::init())
|
||||||
|
.run(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application");
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"distDir": "../dist",
|
||||||
|
"devPath": "http://localhost:5173/",
|
||||||
|
"beforeDevCommand": "pnpm dev",
|
||||||
|
"beforeBuildCommand": "pnpm build",
|
||||||
|
"withGlobalTauri": false
|
||||||
|
},
|
||||||
|
"tauri": {
|
||||||
|
"bundle": {
|
||||||
|
"active": true,
|
||||||
|
"targets": "all",
|
||||||
|
"identifier": "com.tauri.dev",
|
||||||
|
"icon": [
|
||||||
|
"icons/32x32.png",
|
||||||
|
"icons/128x128.png",
|
||||||
|
"icons/128x128@2x.png",
|
||||||
|
"icons/icon.icns",
|
||||||
|
"icons/icon.ico"
|
||||||
|
],
|
||||||
|
"resources": [],
|
||||||
|
"externalBin": [],
|
||||||
|
"copyright": "",
|
||||||
|
"category": "DeveloperTool",
|
||||||
|
"shortDescription": "",
|
||||||
|
"longDescription": "",
|
||||||
|
"deb": {
|
||||||
|
"depends": []
|
||||||
|
},
|
||||||
|
"macOS": {
|
||||||
|
"frameworks": [],
|
||||||
|
"minimumSystemVersion": "",
|
||||||
|
"exceptionDomain": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"allowlist": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"title": "Tauri App",
|
||||||
|
"width": 800,
|
||||||
|
"height": 600,
|
||||||
|
"resizable": true,
|
||||||
|
"fullscreen": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"security": {
|
||||||
|
"csp": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
|
// for information about these interfaces
|
||||||
|
// and what to do when importing types
|
||||||
|
declare namespace App {
|
||||||
|
// interface Error {}
|
||||||
|
// interface Locals {}
|
||||||
|
// interface PageData {}
|
||||||
|
// interface Platform {}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<link rel="stylesheet" href="/global.css" />
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,35 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import WebSocket from 'tauri-plugin-websocket-api'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
|
||||||
|
let ws
|
||||||
|
let response = ''
|
||||||
|
let message = ''
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
ws = await WebSocket.connect('ws://127.0.0.1:8080').then(r => {
|
||||||
|
_updateResponse('Connected')
|
||||||
|
return r
|
||||||
|
}).catch(_updateResponse)
|
||||||
|
ws.addListener(_updateResponse)
|
||||||
|
})
|
||||||
|
|
||||||
|
function _updateResponse(returnValue) {
|
||||||
|
response += (typeof returnValue === 'string' ? returnValue : JSON.stringify(returnValue)) + '<br>'
|
||||||
|
}
|
||||||
|
|
||||||
|
function send() {
|
||||||
|
ws.send(message).then(() => _updateResponse('Message sent')).catch(_updateResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnect() {
|
||||||
|
ws.disconnect().then(() => _updateResponse('Disconnected')).catch(_updateResponse)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input bind:value={message}>
|
||||||
|
<button on:click={send}>Send</button>
|
||||||
|
<button on:click={disconnect}>Disconnect</button>
|
||||||
|
</div>
|
||||||
|
<div>{@html response}</div>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,68 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
|
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgb(0, 100, 200);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: rgb(0, 80, 160);
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
-webkit-padding: 0.4em 0;
|
||||||
|
padding: 0.4em;
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
color: #333;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(:disabled):active {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus {
|
||||||
|
border-color: #666;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
import adapter from "@sveltejs/adapter-auto";
|
||||||
|
import { vitePreprocess } from "@sveltejs/kit/vite";
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
|
||||||
|
kit: {
|
||||||
|
adapter: adapter(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||||
|
//
|
||||||
|
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||||
|
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import { sveltekit } from "@sveltejs/kit/vite";
|
||||||
|
import type { UserConfig } from "vite";
|
||||||
|
|
||||||
|
const config: UserConfig = {
|
||||||
|
plugins: [sveltekit()],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
@ -1,3 +1,3 @@
|
|||||||
packages:
|
packages:
|
||||||
- plugins/*
|
- plugins/*
|
||||||
- plugins/*/examples/*
|
- plugins/*/examples/*
|
||||||
|