前提
React + Expressで画像・動画投稿ができるシステムを作っております。
純粋にフロント側で画像をbase64に変換し、サーバー側へポストする方法で実装したのですが
base64への変換に時間がかかりすぎるためwasmを使ってみました。
wasmに繋いで適当にコンソール出力できるところまではできています。
実現したいこと
Reactから画像ファイルをwasmに渡し、wasmでbase64への変換を行いその変換結果をReactに返すということを行いたいです。
解決したいこと①Go側で画像ファイルが渡されているのかを確認できる方法を知りたい
解決したいこと②もし画像ファイルが渡されている場合どのようにエンコードすれば良いか。(os.Openに何を渡せば良いかが分かればなんとか行けそうな気がしています。)
発生している問題・エラーメッセージ
wasm側の関数を呼び出すことはできているがファイルが渡せているのか確認する方法がわからない。
ファイルを引数として受けれているのならGoでこのように受けたファイルをどのようにエンコードできるのかわからない。
該当のソースコード
wasm.js
javascript
1const go = new window.Go() 2 3export default go
Form.jsx
javascript
1import React, { useState } from 'react' 2import { TextField, Button, Typography, Paper } from '@material-ui/core'; 3import { useDispatch } from 'react-redux' 4import { createChat } from '../../../actions/chats'; 5import useStyles from './styles' 6 7import go from '../../../actions/wasm' 8 9const Form = ({ gossipId }) => { 10 const classes = useStyles() 11 const [chatData, setChatData] = useState({message: '', selectedFile: ''}) 12 const user = JSON.parse(localStorage.getItem('profile')) 13 const dispatch = useDispatch() 14 const [ imageFile, setImageFile ] = useState({identify: '', file: null}) 15 const reader = new FileReader 16 17 const uploadFile = async () => { 18 let val = null 19 let sample = null 20 reader.readAsDataURL(imageFile.file) 21 reader.addEventListener('load', async () => { 22 await WebAssembly.instantiateStreaming(fetch("/wasm/main.wasm"), go.importObject).then((result) => { 23 go.run(result.instance) 24 sample = window.test(imageFile.file) 25 }).catch((err) => { 26 console.log(err) 27 }) 28 29 val = reader.result.replace(/data:.*\/.*base64,/,'') 30 dispatch(createChat({ 31 ...chatData, 32 name: user?.result?.name, 33 gossip: gossipId, 34 userId: user.result._id ? user.result._id : user.result.googleId, 35 file: val, 36 identify: imageFile.identify, 37 test: sample 38 })) 39 }) 40 } 41 42 const handleSubmit = async (e) => { 43 console.log('submit clicked') 44 e.preventDefault() 45 if (imageFile.file) { 46 uploadFile() 47 }else{ 48 dispatch(createChat({ ...chatData, name: user?.result?.name, gossip: gossipId, userId: user.result._id ? user.result._id : user.result.googleId})) 49 } 50 clear() 51 } 52 53 const clear = () => { 54 setChatData({message: '', selectedFile: ''}) 55 setImageFile({identify: '', file: null}) 56 } 57 58 const fileSet = (e) => { 59 const files = e.target.files 60 const file = files[0] 61 const time = new Date().getTime() 62 const identify = `chats/${user?.result?._id ? user?.result?._id : user?.result?.googleId}_${time}_${file.name}` 63 64 setImageFile({identify: identify, file: file}) 65 setChatData({ ...chatData, selectedFile: identify }) 66 } 67 68 if(!user?.result?.name){ 69 return ( 70 <Paper className={classes.chatFormPaper}> 71 <Typography variant='h6' align='center'> 72 Please Sign In to Create Your Own Chat and Like Other's Chat 73 </Typography> 74 </Paper> 75 ) 76 } 77 return ( 78 <Paper className={classes.chatFormPaper}> 79 <form className={classes.form} autoComplete='off' noValidate onSubmit={ handleSubmit }> 80 <Typography className={classes.formTitle} variant='h6' align='center'>Let's exchange opinions</Typography> 81 <TextField 82 className={classes.messageForm} 83 name='message' 84 variant='outlined' 85 label='Message' 86 multiline 87 rows={3} 88 fullWidth 89 value={chatData.message} 90 onChange={e => setChatData({ ...chatData, message: e.target.value })} 91 /> 92 <div className={classes.imageForm}> 93 <input type='file' multiple={false} onChange={(e) => fileSet(e)}/> 94 </div> 95 <Button variant='contained' color='primary' size="large" type="submit" fullWidth>Submit</Button> 96 </form> 97 </Paper> 98 ) 99} 100 101export default Form
main.go
go
1// コメントアウト部分が実行できればと考えています。 2package main 3 4import ( 5 "syscall/js" 6 "fmt" 7 // "os" 8 // "io/ioutil" 9 // "encoding/base64" 10) 11 12func test(this js.Value, vs []js.Value) interface{}{ 13 fmt.Println(this) 14 fmt.Println(vs) 15 fmt.Println(vs[0]) 16 // f, err := os.Open(vs[0].String()) 17 // if err != nil { 18 // panic(err) 19 // } 20 // defer f.Close() 21 22 // b, _ := ioutil.ReadAll(f) 23 // out, _ := os.Create("out") 24 // base64.NewEncoder(base64.StdEncoding, out).Write(b) 25 return "hogehoge" 26} 27 28func setFuncs(){ 29 js.Global().Set("test", js.FuncOf(test)) 30} 31 32func main () { 33 fmt.Println("App assembly process start") 34 setFuncs() 35 done := make(chan struct{}, 0) 36 <-done 37}
試したこと
実際に上記main.goのコメントアウトを外して動作を確認
main.go
go
1package main 2 3import ( 4 "syscall/js" 5 "fmt" 6 "os" 7 "io/ioutil" 8 "encoding/base64" 9) 10 11type General interface {} 12 13func test(this js.Value, vs []js.Value) interface{}{ 14 // fmt.Println(this) 15 // fmt.Println(vs) 16 // fmt.Println(vs[0]) 17 f, err := os.Open(vs[0].String()) 18 if err != nil { 19 panic(err) 20 } 21 defer f.Close() 22 23 b, _ := ioutil.ReadAll(f) 24 out, _ := os.Create("out") 25 base64.NewEncoder(base64.StdEncoding, out).Write(b) 26 return "hogehoge" 27} 28 29func setFuncs(){ 30 js.Global().Set("test", js.FuncOf(test)) 31} 32 33func main () { 34 fmt.Println("App assembly process start") 35 setFuncs() 36 done := make(chan struct{}, 0) 37 <-done 38}
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答2件
あなたの回答
tips
プレビュー