function redirectPage() {
const isMobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);
const isLandscape = window.matchMedia("(orientation: landscape)").matches;
if (isMobile && isLandscape) {
window.location.href = "mobile-landscape.html"; // 모바일 가로용 페이지
} else if (!isMobile) {
window.location.href = "desktop.html"; // PC용 페이지
} else {
window.location.href = "mobile.html"; // 모바일 세로용 페이지
}
}
// 페이지 로드 시 실행
redirectPage();
// 화면 크기 변경 시 다시 체크 (예: 모바일에서 가로/세로 전환)
window.addEventListener("resize", redirectPage);
'프로그램개발'에 해당되는 글 136건
- 2025.04.03 모바일 페이지, pc 페이지 구분
- 2025.04.03 2d to 3d
- 2025.03.28 안드로이드 라이브러리 다운받기
- 2025.03.25 unity nats 샘플
- 2025.03.24 unity에서 NATS 사용하기
- 2025.03.23 파이썬으로 youtube 다운받기
- 2025.03.04 websocket지원 메세지큐
- 2025.02.26 텍스트파일 인코딩 utf8로 전환
- 2025.02.22 unitask
- 2024.05.22 c# 서버에서 코루틴과 await을 사용시 장단점
using System;
using System.Text;
using NATS.Client;
using NATS.Net;
using Systehttp://m.Threading.Tasks;
using NATS.Client.Core;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class NatSample : MonoBehaviour
{
private NatsClient client;
private const string NATS_URL = "ws://35.208.138.76:8282"; // NATS 서버 주소
private Dictionary<string, IAsyncSubscription<string>> subscriptions = new Dictionary<string, IAsyncSubscription<string>>();
async void Start()
{
await ConnectToNats();
}
async Task ConnectToNats()
{
try
{
client = new NatsClient(new NatsOpts { Url = NATS_URL });
Debug.Log("Connected to NATS server");
}
catch (Exception e)
{
Debug.LogError($"NATS Connection Error: {e.Message}");
}
}
public async Task AddSubject(string subject)
{
if (client == null || subscriptions.ContainsKey(subject))
return;
try
{
var subscription = client.SubscribeAsync<string>(subject);
subscriptions[subject] = subscription;
_ = Task.Run(async () =>
{
await foreach (var msg in subscription)
{
Debug.Log($"Received on {subject}: {msg.Data}");
UpdateChatDisplay($"{subject}: {msg.Data}");
}
});
Debug.Log($"Added subscription to subject: {subject}");
}
catch (Exception e)
{
Debug.LogError($"Error adding subject {subject}: {e.Message}");
}
}
public async Task RemoveSubject(string subject)
{
if (client == null || !subscriptions.ContainsKey(subject))
return;
try
{
await subscriptions[subject].DisposeAsync();
subscriptions.Remove(subject);
Debug.Log($"Removed subscription from subject: {subject}");
}
catch (Exception e)
{
Debug.LogError($"Error removing subject {subject}: {e.Message}");
}
}
public async Task SendMessage(string subject, string message)
{
if (client == null) return;
try
{
await client.PublishAsync(subject, message);
Debug.Log($"Sent to {subject}: {message}");
}
catch (Exception e)
{
Debug.LogError($"Error sending message: {e.Message}");
}
}
void UpdateChatDisplay(string message)
{
Debug.Log("msg:" + message);
}
async void OnApplicationQuit()
{
if (client != null)
{
foreach (var subscription in subscriptions.Values)
{
await subscription.DisposeAsync();
}
await client.DisposeAsync();
}
}
}
using System;
using System.Text;
using NATS.Client;
using NATS.Net;
using System.Threading.Tasks;
using NATS.Client.Core;
using UnityEngine;
using UnityEngine.UI;
public class NatSample : MonoBehaviour
{
private NatsClient client;
//private const string NATS_URL = "nats://localhost:4222"; // NATS 서버 주소
private const string NATS_URL = "ws://localhost:8282"; // NATS 서버 주소
private const string SUBJECT = "test"; // 채팅 채널
async void Start()
{
await ConnectToNats();
}
async Task ConnectToNats()
{
try
{
client = new NatsClient(new NatsOpts { Url = NATS_URL });
await foreach (var msg in client.SubscribeAsync<string>(SUBJECT))
{
Debug.Log($"Received: {msg}");
UpdateChatDisplay(msg.Data);
}
}
catch (Exception e)
{
Debug.LogError($"NATS Connection Error: {e.Message}");
}
}
float t = 0.0f;
private void Update()
{
t += Time.deltaTime;
if (t>3)
{
t = 0;
SendMessage2();
}
}
public async void SendMessage2()
{
if (client == null ) return;
await client.PublishAsync(SUBJECT, "1a2a");
}
void UpdateChatDisplay(string message)
{
Debug.Log("msg:"+ message);
}
async void OnApplicationQuit()
{
if (client != null)
{
await client.DisposeAsync();
}
}
}
import yt_dlp
def download_video(url, output_path="downloads/%(title)s.%(ext)s"):
ydl_opts = {
"outtmpl": output_path, # 파일 저장 경로 및 이름 설정
"format": "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]", # 최고 화질 비디오+오디오 조합
"noplaylist": True, # 개별 비디오만 다운로드
"merge_output_format": "mp4", # 병합 시 MP4로 저장
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
# 예제 실행
video_url = "https://www.youtube.com/watch?v="
download_video(video_url)
WebSocket을 기본적으로 지원하는 메시지 큐(Message Queue) 시스템은 많지 않지만, WebSocket과 쉽게 통합할 수 있는 몇 가지 메시지 브로커와 솔루션이 있습니다
1. NATS
- WebSocket 지원: 기본적으로 WebSocket 지원 추가됨 (공식 문서)
- 사용 방법:
- WebSocket을 직접 사용하여 메시지를 송수신 가능
2. EMQX (MQTT Broker)
- WebSocket 지원: 기본적으로 WebSocket을 지원
- 사용 방법:
- MQTT 프로토콜을 WebSocket과 함께 사용하여 메시지 큐 기능 구현 가능
3. Mosquitto (MQTT Broker)
- WebSocket 지원: 직접 지원
- 사용 방법:
- mosquitto.conf에서 WebSocket 리스너 설정 후 사용 가능
import os
import chardet
def convert\_to\_utf8(folder\_path):
for root, \_, files in os.walk(folder\_path):
for file in files:
if file.endswith(".cs"): # .cs 파일만 선택
file\_path = os.path.join(root, file)
with open(file\_path, 'rb') as f:
raw\_data = f.read()
detected = chardet.detect(raw\_data) # 인코딩 감지
encoding = detected\['encoding'\] if detected\['encoding'\] else 'utf-8'
if encoding.lower() != 'utf-8':
try:
text = raw\_data.decode(encoding)
with open(file\_path, 'w', encoding='utf-8') as f:
f.write(text)
print(f"Converted: {file\_path} from {encoding} to UTF-8")
except Exception as e:
print(f"Failed to convert {file\_path}: {e}")
else:
print(f"Skipped (already UTF-8): {file\_path}")
# 사용 예시
folder\_path = "C:/your/folder/path" # 변경 필요
convert\_to\_utf8(folder\_path)
기존 소스을 변경시
Task 은 UniTask로 변경
async Task => async UniTask 로
async void => async UniTaskVoid 로
Forget() 처리가 가능할 경우 로 async UniTaskVoid 로 처리
testA.Forget();
async UniTaskVoid testA()
{
}
async 가 필요없는 삭제할것
UniTask SomeFunction() { // 아무것도 하지 않음 return UniTask.CompletedTask; }
UniTaskVoid는 await할 수 없음
UniTaskVoid는 일반적인 UniTask와 다르게 await할 수 없습니다.
만약 비동기적으로 호출해야 한다면, UniTaskVoid 대신 UniTask를 사용하세요.
async UniTaskVoid Test() { await UniTask.Delay(500); Debug.Log("완료"); } // ❌ 잘못된 코드 (await 불가능) // await Test(); // 컴파일 에러 발생!
기존 함수 Get;Set; 으로 되었는건 await 함수로 만들것
UniTaskVoid 정리
특징설명
리턴값 없음 | return;을 명시적으로 쓰지 않아도 됨 |
자동 실행됨 | Forget() 없이도 실행됨 |
await 필수 | await이 없으면 경고 발생 |
예외 전파됨 | try-catch로 예외를 직접 처리해야 함 |
await 불가능 | UniTaskVoid는 await할 수 없음 → UniTask를 사용해야 함 |
추천: UniTaskVoid는 주로 Unity의 이벤트 기반 코드(Update, OnTriggerEnter 등)에서 사용하고, 일반적인 비동기 함수에서는 UniTask를 사용하는 것이 더 안전합니다.
코루틴 -> To.Coroutine()
Forget() 사용시 이후 코드와 동시혹은 늦게 되어도 상관없는 코드일경우에 적용하고
문제 발생하면 상위 단계로 올라가서 Forget() 처리
webgl 빌드시
- UniTask.RunOnThreadPool() ❌ → WebGL에서는 사용 불가
- await Task.Delay(1000); ❌ → 대신 UniTask.Delay() 사용
- UniTask.Yield(PlayerLoopTiming.Background) ❌ → 대신 Update 사용
- async void ❌ → async UniTask 또는 async Task 사용
- UnityWebRequest 사용 시 CORS 문제 주의
c# 서버에서 코루틴과 await을 사용시 장단점
코루틴 만 사용하면 빠름
await 코루틴 같이 사용하면 느림 50 cpu
await 만 사용하면 14 cpu
ai
싱글쓰레드처럼 처리하기 위해선 코루틴이 좋아보임이지만 결과값 리턴 하는 경우 좀 지저분해짐