mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-18 22:30:40 -07:00
Update server URL handling and improve logging
- Changed the server URL from 'http://localhost:8000' to 'http://127.0.0.1:17493' in the server store and connection form. - Enhanced server startup logging to display the dynamically assigned server URL. - Updated server management logic in main.rs to reflect the new port configuration and improve orphaned process handling.
This commit is contained in:
+4
-2
@@ -94,8 +94,10 @@ function App() {
|
|||||||
console.log('Production mode: Starting bundled server...');
|
console.log('Production mode: Starting bundled server...');
|
||||||
|
|
||||||
startServer(false)
|
startServer(false)
|
||||||
.then(() => {
|
.then((serverUrl) => {
|
||||||
console.log('Server is ready');
|
console.log('Server is ready at:', serverUrl);
|
||||||
|
// Update the server URL in the store with the dynamically assigned port
|
||||||
|
useServerStore.getState().setServerUrl(serverUrl);
|
||||||
setServerReady(true);
|
setServerReady(true);
|
||||||
// Mark that we started the server (so we know to stop it on close)
|
// Mark that we started the server (so we know to stop it on close)
|
||||||
// @ts-expect-error - adding property to window
|
// @ts-expect-error - adding property to window
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export function ConnectionForm() {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Server URL</FormLabel>
|
<FormLabel>Server URL</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="http://localhost:8000" {...field} />
|
<Input placeholder="http://127.0.0.1:17493" {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>Enter the URL of your voicebox backend server</FormDescription>
|
<FormDescription>Enter the URL of your voicebox backend server</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface ServerStore {
|
|||||||
export const useServerStore = create<ServerStore>()(
|
export const useServerStore = create<ServerStore>()(
|
||||||
persist(
|
persist(
|
||||||
(set) => ({
|
(set) => ({
|
||||||
serverUrl: 'http://localhost:8000',
|
serverUrl: 'http://127.0.0.1:17493',
|
||||||
setServerUrl: (url) => set({ serverUrl: url }),
|
setServerUrl: (url) => set({ serverUrl: url }),
|
||||||
|
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
|
|||||||
@@ -74,10 +74,8 @@ export async function getLatestRelease(): Promise<ReleaseInfo> {
|
|||||||
const releaseInfo: ReleaseInfo = {
|
const releaseInfo: ReleaseInfo = {
|
||||||
version,
|
version,
|
||||||
downloadLinks: {
|
downloadLinks: {
|
||||||
macArm:
|
macArm: downloadLinks.macArm || `${baseUrl}/voicebox_aarch64.app.tar.gz`,
|
||||||
downloadLinks.macArm || `${baseUrl}/voicebox_aarch64.app.tar.gz`,
|
macIntel: downloadLinks.macIntel || `${baseUrl}/voicebox_x64.app.tar.gz`,
|
||||||
macIntel:
|
|
||||||
downloadLinks.macIntel || `${baseUrl}/voicebox_x64.app.tar.gz`,
|
|
||||||
windows:
|
windows:
|
||||||
downloadLinks.windows || `${baseUrl}/voicebox_${version.replace('v', '')}_x64_en-US.msi`,
|
downloadLinks.windows || `${baseUrl}/voicebox_${version.replace('v', '')}_x64_en-US.msi`,
|
||||||
linux: downloadLinks.linux || `${baseUrl}/voicebox_x86_64-unknown-linux-gnu.AppImage`,
|
linux: downloadLinks.linux || `${baseUrl}/voicebox_x86_64-unknown-linux-gnu.AppImage`,
|
||||||
|
|||||||
Binary file not shown.
+73
-47
@@ -8,6 +8,9 @@ use tauri::{command, State, Manager, WindowEvent, Emitter, Listener, RunEvent};
|
|||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
|
const LEGACY_PORT: u16 = 8000;
|
||||||
|
const SERVER_PORT: u16 = 17493;
|
||||||
|
|
||||||
struct ServerState {
|
struct ServerState {
|
||||||
child: Mutex<Option<tauri_plugin_shell::process::CommandChild>>,
|
child: Mutex<Option<tauri_plugin_shell::process::CommandChild>>,
|
||||||
server_pid: Mutex<Option<u32>>,
|
server_pid: Mutex<Option<u32>>,
|
||||||
@@ -22,63 +25,84 @@ async fn start_server(
|
|||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
// Check if server is already running (managed by this app instance)
|
// Check if server is already running (managed by this app instance)
|
||||||
if state.child.lock().unwrap().is_some() {
|
if state.child.lock().unwrap().is_some() {
|
||||||
return Ok("Server already running on http://localhost:8000".to_string());
|
return Ok(format!("http://127.0.0.1:{}", SERVER_PORT));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If keep_running_on_close is false, kill any orphaned server from previous session
|
// Kill any orphaned voicebox-server from previous session on legacy port 8000
|
||||||
let keep_running = *state.keep_running_on_close.lock().unwrap();
|
// This handles upgrades from older versions that used a fixed port
|
||||||
if !keep_running {
|
#[cfg(unix)]
|
||||||
#[cfg(unix)]
|
{
|
||||||
|
use std::process::Command;
|
||||||
|
// Find processes listening on legacy port 8000 with their command names
|
||||||
|
if let Ok(output) = Command::new("lsof")
|
||||||
|
.args(["-i", &format!(":{}", LEGACY_PORT), "-sTCP:LISTEN"])
|
||||||
|
.output()
|
||||||
{
|
{
|
||||||
use std::process::Command;
|
let output_str = String::from_utf8_lossy(&output.stdout);
|
||||||
// Find any process listening on port 8000
|
for line in output_str.lines().skip(1) { // Skip header line
|
||||||
if let Ok(output) = Command::new("lsof")
|
// lsof output format: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
||||||
.args(["-ti", ":8000"])
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||||
.output()
|
if parts.len() >= 2 {
|
||||||
{
|
let command = parts[0];
|
||||||
let pids = String::from_utf8_lossy(&output.stdout);
|
let pid_str = parts[1];
|
||||||
for pid_str in pids.lines() {
|
|
||||||
if let Ok(pid) = pid_str.trim().parse::<i32>() {
|
// Only kill if it's a voicebox-server process
|
||||||
println!("Found orphaned server on port 8000 (PID: {}), killing it...", pid);
|
if command.contains("voicebox") {
|
||||||
// Kill the process group
|
if let Ok(pid) = pid_str.parse::<i32>() {
|
||||||
let _ = Command::new("kill")
|
println!("Found orphaned voicebox-server on legacy port {} (PID: {}, CMD: {}), killing it...", LEGACY_PORT, pid, command);
|
||||||
.args(["-9", "--", &format!("-{}", pid)])
|
// Kill the process group
|
||||||
.output();
|
let _ = Command::new("kill")
|
||||||
let _ = Command::new("kill")
|
.args(["-9", "--", &format!("-{}", pid)])
|
||||||
.args(["-9", &pid.to_string()])
|
.output();
|
||||||
.output();
|
let _ = Command::new("kill")
|
||||||
|
.args(["-9", &pid.to_string()])
|
||||||
|
.output();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Legacy port {} is in use by non-voicebox process: {} (PID: {}), not killing", LEGACY_PORT, command, pid_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#[cfg(windows)]
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
use std::process::Command;
|
||||||
|
// On Windows, find PIDs on legacy port 8000, then check their names
|
||||||
|
if let Ok(output) = Command::new("netstat")
|
||||||
|
.args(["-ano"])
|
||||||
|
.output()
|
||||||
{
|
{
|
||||||
use std::process::Command;
|
let output_str = String::from_utf8_lossy(&output.stdout);
|
||||||
// On Windows, find and kill process on port 8000
|
for line in output_str.lines() {
|
||||||
if let Ok(output) = Command::new("netstat")
|
if line.contains(&format!(":{}", LEGACY_PORT)) && line.contains("LISTENING") {
|
||||||
.args(["-ano"])
|
if let Some(pid_str) = line.split_whitespace().last() {
|
||||||
.output()
|
if let Ok(pid) = pid_str.parse::<u32>() {
|
||||||
{
|
// Get process name for this PID
|
||||||
let output_str = String::from_utf8_lossy(&output.stdout);
|
if let Ok(tasklist_output) = Command::new("tasklist")
|
||||||
for line in output_str.lines() {
|
.args(["/FI", &format!("PID eq {}", pid), "/FO", "CSV", "/NH"])
|
||||||
if line.contains(":8000") && line.contains("LISTENING") {
|
.output()
|
||||||
if let Some(pid_str) = line.split_whitespace().last() {
|
{
|
||||||
if let Ok(pid) = pid_str.parse::<u32>() {
|
let tasklist_str = String::from_utf8_lossy(&tasklist_output.stdout);
|
||||||
println!("Found orphaned server on port 8000 (PID: {}), killing it...", pid);
|
if tasklist_str.to_lowercase().contains("voicebox") {
|
||||||
let _ = Command::new("taskkill")
|
println!("Found orphaned voicebox-server on legacy port {} (PID: {}), killing it...", LEGACY_PORT, pid);
|
||||||
.args(["/PID", &pid.to_string(), "/T", "/F"])
|
let _ = Command::new("taskkill")
|
||||||
.output();
|
.args(["/PID", &pid.to_string(), "/T", "/F"])
|
||||||
|
.output();
|
||||||
|
} else {
|
||||||
|
println!("Legacy port {} is in use by non-voicebox process (PID: {}), not killing", LEGACY_PORT, pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Brief wait for port to be released
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Brief wait for port to be released
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(200));
|
||||||
|
|
||||||
// Get app data directory
|
// Get app data directory
|
||||||
let data_dir = app
|
let data_dir = app
|
||||||
@@ -106,12 +130,14 @@ async fn start_server(
|
|||||||
|
|
||||||
println!("Sidecar command created successfully");
|
println!("Sidecar command created successfully");
|
||||||
|
|
||||||
// Pass data directory to Python server
|
// Pass data directory and port to Python server
|
||||||
sidecar = sidecar.args([
|
sidecar = sidecar.args([
|
||||||
"--data-dir",
|
"--data-dir",
|
||||||
data_dir
|
data_dir
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| "Invalid data dir path".to_string())?,
|
.ok_or_else(|| "Invalid data dir path".to_string())?,
|
||||||
|
"--port",
|
||||||
|
&SERVER_PORT.to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if remote.unwrap_or(false) {
|
if remote.unwrap_or(false) {
|
||||||
@@ -134,9 +160,9 @@ async fn start_server(
|
|||||||
println!("Server process spawned, waiting for ready signal...");
|
println!("Server process spawned, waiting for ready signal...");
|
||||||
println!("=================================================================");
|
println!("=================================================================");
|
||||||
|
|
||||||
// Store child process and its PID for process group killing
|
// Store child process and PID
|
||||||
let pid = child.pid();
|
let process_pid = child.pid();
|
||||||
*state.server_pid.lock().unwrap() = Some(pid);
|
*state.server_pid.lock().unwrap() = Some(process_pid);
|
||||||
*state.child.lock().unwrap() = Some(child);
|
*state.child.lock().unwrap() = Some(child);
|
||||||
|
|
||||||
// Wait for server to be ready by listening for startup log
|
// Wait for server to be ready by listening for startup log
|
||||||
@@ -215,7 +241,7 @@ async fn start_server(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok("Server started on http://localhost:8000".to_string())
|
Ok(format!("http://127.0.0.1:{}", SERVER_PORT))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "voicebox",
|
"productName": "Voicebox",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"identifier": "sh.voicebox.app",
|
"identifier": "sh.voicebox.app",
|
||||||
"build": {
|
"build": {
|
||||||
|
|||||||
Reference in New Issue
Block a user